summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--docker.html.markdown146
-rw-r--r--hdl.html.markdown231
-rw-r--r--python3.html.markdown16
-rw-r--r--rust.html.markdown2
-rw-r--r--standard-ml.html.markdown5
-rw-r--r--typescript.html.markdown2
-rw-r--r--vimscript.html.markdown651
7 files changed, 1033 insertions, 20 deletions
diff --git a/docker.html.markdown b/docker.html.markdown
new file mode 100644
index 00000000..24f85247
--- /dev/null
+++ b/docker.html.markdown
@@ -0,0 +1,146 @@
+---
+language: docker
+filename: docker.bat
+contributors:
+ - ["Ruslan López", "http://javapro.org/"]
+---
+
+```
+:: download, install and run hello-world image
+docker run hello-world
+
+:: if this is the first time you should be able to see the message
+:: Unable to find image 'hello-world:latest' locally
+:: latest: Pulling from library/hello-world
+:: 1b930d010525: Pull complete
+:: Digest: sha256:4fe721ccc2e8dc7362278a29dc660d833570ec2682f4e4194f4ee23e415e1064
+:: Status: Downloaded newer image for hello-world:latest
+::
+:: Hello from Docker!
+:: This message shows that your installation appears to be working correctly.
+::
+:: To generate this message, Docker took the following steps:
+:: 1. The Docker client contacted the Docker daemon.
+:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
+:: (amd64)
+:: 3. The Docker daemon created a new container from that image which runs the
+:: executable that produces the output you are currently reading.
+:: 4. The Docker daemon streamed that output to the Docker client, which sent it
+:: to your terminal.
+::
+:: To try something more ambitious, you can run an Ubuntu container with:
+:: $ docker run -it ubuntu bash
+::
+:: Share images, automate workflows, and more with a free Docker ID:
+:: https://hub.docker.com/
+::
+:: For more examples and ideas, visit:
+:: https://docs.docker.com/get-started/
+
+:: now lets see currently running images
+docker ps
+:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
+:: NAMES
+
+:: lets see the images we have ran previously
+docker ps -a
+
+:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
+:: NAMES
+:: 4a76281f9c53 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago
+:: happy_poincare
+:: the name part is generated automatically so it probably will be different for you
+
+:: let's remove our previously generated image
+docker rm happy_poincare
+
+:: lets test if it was really deleted
+docker ps -a
+:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
+:: NAMES
+
+:: specify a custom name for the container
+docker run --name test_container hello-world
+:: Hello from Docker!
+:: This message shows that your installation appears to be working correctly.
+::
+:: To generate this message, Docker took the following steps:
+:: 1. The Docker client contacted the Docker daemon.
+:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
+:: (amd64)
+:: 3. The Docker daemon created a new container from that image which runs the
+:: executable that produces the output you are currently reading.
+:: 4. The Docker daemon streamed that output to the Docker client, which sent it
+:: to your terminal.
+::
+:: To try something more ambitious, you can run an Ubuntu container with:
+:: $ docker run -it ubuntu bash
+::
+:: Share images, automate workflows, and more with a free Docker ID:
+:: https://hub.docker.com/
+::
+:: For more examples and ideas, visit:
+:: https://docs.docker.com/get-started/
+
+docker ps -a
+:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
+:: NAMES
+:: d345fe1a4f41 hello-world "/hello" About a minute ago Exited (0) About a minute ago
+:: test_container
+:: as you can see the name is now what we have specified
+
+:: retireve logs from a named container
+docker logs test_container
+:: Hello from Docker!
+:: This message shows that your installation appears to be working correctly.
+::
+:: To generate this message, Docker took the following steps:
+:: 1. The Docker client contacted the Docker daemon.
+:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
+:: (amd64)
+:: 3. The Docker daemon created a new container from that image which runs the
+:: executable that produces the output you are currently reading.
+:: 4. The Docker daemon streamed that output to the Docker client, which sent it
+:: to your terminal.
+::
+:: To try something more ambitious, you can run an Ubuntu container with:
+:: $ docker run -it ubuntu bash
+::
+:: Share images, automate workflows, and more with a free Docker ID:
+:: https://hub.docker.com/
+::
+:: For more examples and ideas, visit:
+:: https://docs.docker.com/get-started/
+
+docker rm test_container
+
+docker run ubuntu
+:: Unable to find image 'ubuntu:latest' locally
+:: latest: Pulling from library/ubuntu
+:: 2746a4a261c9: Pull complete
+:: 4c1d20cdee96: Pull complete 0d3160e1d0de: Pull complete c8e37668deea: Pull complete Digest: sha256:250cc6f3f3ffc5cdaa9d8f4946ac79821aafb4d3afc93928f0de9336eba21aa4
+:: Status: Downloaded newer image for ubuntu:latest
+
+docker ps -a
+:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
+:: NAMES
+:: c19e9e5b000a ubuntu "/bin/bash" 5 seconds ago Exited (0) 4 seconds ago
+:: relaxed_nobel
+
+:: running a container in an interactive mode
+docker run -it ubuntu
+:: root@e2cac48323d2:/# uname
+:: Linux
+:: root@e2cac48323d2:/# exit
+:: exit
+
+docker rm relaxed_nobel
+
+docker ps -a
+:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
+:: NAMES
+:: e2cac48323d2 ubuntu "/bin/bash" 2 minutes ago Exited (0) About a minute ago
+:: nifty_goldwasser
+
+docker rm nifty_goldwasser
+``` \ No newline at end of file
diff --git a/hdl.html.markdown b/hdl.html.markdown
new file mode 100644
index 00000000..cad07817
--- /dev/null
+++ b/hdl.html.markdown
@@ -0,0 +1,231 @@
+---
+language: hdl
+filename: learnhdl.hdl
+contributors:
+ - ["Jack Smith", "https://github.com/JSmithTech2019"]
+---
+
+HDL (hardware description language) is a specialized language used to describe the structure/behavior of real world circuits.
+
+It is used by circuit designers to simulate circuits and logic prior to wiring and fabricating a hardware circuit.
+
+HDL allows circuit designers to simulate circuits at a high level without being connected to specific components.
+
+## Basic building blocks & introduction to the language---
+This programming language is built by simulating hardware chips and wiring. Normal programming functions are replaced with specialized chips that are added to the current wiring desing. Every base chip must be written as it's own file and imported to be used in the current chip, though they may be reused as often as desired.
+
+```verilog
+// Single line comments start with two forward slashes.
+
+/*
+ * Multiline comments can be written using '/*' and 'star/'.
+ * These are often used as comments.
+ *
+ * Note that they cannot be nested and will end at the first 'star/'.
+ */
+
+////////////////////////////////////////////////////
+// 1. Chips & Components
+////////////////////////////////////////////////////
+/*
+ * Unlike other languages HDL creates an individual chip (function) per file
+ * These are defined with a name, input arguments, output arguments
+ * and finally the parts/logic of that specific chip.
+ */
+
+// Note CHIP is capitalized, the chip name does not need to be.
+CHIP Ex {
+ IN a, // Single bit (0 or 1) variable.
+ c[16]; // 16 bit variable bus of single bit values.
+
+ OUT out[16], // 16 bit variable bus output.
+ carry; // Single bit output variable
+
+ PARTS:
+ // The functional components of the chip.
+}
+
+// Lines are ended with semicolons but can be continued using commas. The
+// whitespace is ignored.
+
+
+
+////////////////////////////////////////////////////
+// 2. Inputs, Outputs, & Variables
+////////////////////////////////////////////////////
+/*
+ * Variables and IO are treated as pins/wires and can carry a single bit
+ * of data (0 or 1).
+ */
+
+// Hardware works on low level 0's and 1's, in order to use a constant
+// high or low we use the terms true and false.
+a=false; // This is a 0 value.
+b=true; // This is a 1 value.
+
+// Inputs and outputs can be defined as single bits
+IN a, b; // Creates two single bit inputs
+
+// They can also be defined as busses act as arrays where each
+// index can contain a single bit value.
+OUT c[16]; // Creates a 16 bit output array.
+
+// Bussed values can be accessed using brackets
+a[0] // The first indexed value in the bus a.
+a[0..3] // The first 4 values in the a bus.
+// Values can also be passed in entirety. For example if the function
+// foo() takes an 8 bit input bus and outputs a 2 bit bus:
+foo(in=a[0..7], out=c); // C is now a 2 bit internal bus
+
+
+// Note that internally defined busses cannot be subbussed!
+// To access these elements, output or input them seperately:
+foo(in[0]=false, in[1..7]=a[0..6], out[0]=out1, out[1]=out2);
+// out1 and out2 can then be passed into other circuits within the design.
+
+
+
+////////////////////////////////////////////////////
+// Combining Subsystems
+////////////////////////////////////////////////////
+/*
+ * HDL relies heavily on using smaller "building block" chips to then be
+ * added into larger and more complex designs. Creating the smaller components
+ * and then adding them to the larger circuit allows for fewer lines of code
+ * as well as reduction in total rewriting of code.
+ */
+
+// We are writing the function AND that checks if inputs I and K are both one.
+// To implement this chip we will use the built in NAND gate as well as design
+// a custom NOT gate to invert a single input.
+
+// First we construct the Negation (not) chip. We will use the logically
+// complete gate NAND that is built in for this task.
+CHIP Not {
+ IN i; // Not gates only take one single bit input.
+ OUT o; // The negated value of a.
+
+ PARTS:
+ // Add the input to the built in chip, which then sends output to the NOT
+ // output. This effectively negates the given value.
+ Nand(a=i, b=i, out=o);
+}
+
+// By using the built in NAND gate we were able to construct a NOT gate
+// that works like a real world hardware logic chip. Now we must construct
+// the AND gate using these two gate primitives.
+
+// We define a two input, single output AND gate:
+CHIP And {
+ IN i, k; // Two single bit inputs.
+ OUT o; // One single bit output.
+
+ PARTS:
+ // Insert I and K into the nand gate and store the output in an internal
+ // wire called notOut.
+ Nand(a=i,b=b,out=notOut);
+
+ // Use the not gate we constructed to invert notOut and send to the AND
+ // output.
+ Not(in=notOut,out=o);
+}
+
+// Easy! Now we can use Nand, And, and Not gates in higher level circuits.
+// Many of these low level components are built in to HDL but any chip can
+// be written as a submodule and used in larger designs.
+```
+
+## Test Files
+When working with the nand2tetris hardware simulator chips written using HDL will
+then be processed against test and comparison files to test functionality of the
+simulated chip versus the expected output. To do this a test file will be loaded
+into the hardware simulator and run against the simulated hardware.
+
+```verilog
+// First the chip the test file is written for is loaded
+load <chip name>.hdl
+
+// We set the output file for the simulated chip output as well as the comparison
+// file that it will be tested against. We also specify what the output is
+// expected to look like. In this case there will be two output columns, each
+// will be buffered by a single space on either side and 4 binary values in
+// the center of each column.
+output-file <chip name>.out,
+compare-to <chip name>.cmp,
+output-list in%B1.4.1 out%B1.4.1;
+
+// Then we set initial values for inputs to the chip. For example
+set enable1 1, // set input enable1 to 1
+set enable2 0, // set input enable2 to 0
+
+// The clock is also controlled in the test file using tick and tock. Tick is a
+// positive pulse and tock takes the clock back to 0. Clock cycles can be run
+// multiple times in a row with no other changes to inputs or outputs.
+tick,
+tock,
+
+// Finally we output the first expected value (from the test file) which is then
+// compared with the first line of real output from our HDL circuit. This output
+// can be viewed in the <chip name>.out file.
+output;
+
+// An example of <chip name>, a chip that takes in a 4 bit value as input and
+// adds 1 to that value could have the following as test code:
+
+// Set the input value to 0000, clock pulse, compare output from cmp file to actual out.
+set in %B0000,
+tick,
+tock,
+output;
+
+// Set the input value to 0110, clock pulse, compare output from cmp file to actual out.
+set in %B0110,
+tick,
+tock,
+output;
+
+// The expected output for case 1 should be 0001 and case 2 expects 0111, lets
+// learn a little more about comparison files before finalizing our lesson.
+```
+
+## Comparison Files
+Now lets take a look at comparison files, the files that hold what the test file
+compares with the actual output of an HDL chip in the hardware simulator!
+
+```verilog
+// Like the <chip name> example above, the structure of the comparison file
+// would look something like this
+| in | out |
+| 0000 | 0001 |
+| 0110 | 0111 |
+
+// Notice how the input values specified in the test case are equivalent to the
+// `in` column of the comparison file, and that the space buffer is 1 on either side.
+
+// If the output from the HDL code we not this, such as the output below, then the
+// test will fail and the user will know that the simulated chip is not correctly designed.
+| in | out |
+| 0000 | 0001 |
+| 0110 | 0110 | // Error! The chip did not add 1 here, something went wrong.
+
+
+```
+
+This is incredibly useful as it allows designers to simulate chip logic prior to
+fabricating real life hardware and identify problems in their designs. Be warned that
+errors in the test or comparison files can lead to both false positives and also
+the more damaging false negatives so ensure that the logic is sound behind the test
+creation.
+
+
+Good luck and happy coding!
+
+## Resources
+
+* [From Nand To Tetris](https://www.nand2tetris.org)
+
+## Further Reading
+
+* [Hardware Description Language](https://en.wikipedia.org/wiki/Hardware_description_language)
+
+* [HDL Programming Fundamentals](https://www.electronicdesign.com/products/hdl-programming-fundamentals) \ No newline at end of file
diff --git a/python3.html.markdown b/python3.html.markdown
index 2b7c9490..f69ffb14 100644
--- a/python3.html.markdown
+++ b/python3.html.markdown
@@ -16,8 +16,6 @@ Python was created by Guido van Rossum in the early 90s. It is now one of the mo
languages in existence. I fell in love with Python for its syntactic clarity. It's basically
executable pseudocode.
-Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or louiedinh [at] [google's email service]
-
Note: This article applies to Python 3 specifically. Check out [here](http://learnxinyminutes.com/docs/python/) if you want to learn the old Python 2.7
```python
@@ -139,20 +137,6 @@ b == a # => True, a's and b's objects are equal
# You can find the length of a string
len("This is a string") # => 16
-# .format can be used to format strings, like this:
-"{} can be {}".format("Strings", "interpolated") # => "Strings can be interpolated"
-
-# You can repeat the formatting arguments to save some typing.
-"{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick")
-# => "Jack be nimble, Jack be quick, Jack jump over the candle stick"
-
-# You can use keywords if you don't want to count.
-"{name} wants to eat {food}".format(name="Bob", food="lasagna") # => "Bob wants to eat lasagna"
-
-# If your Python 3 code also needs to run on Python 2.5 and below, you can also
-# still use the old style of formatting:
-"%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the old way"
-
# You can also format using f-strings or formatted string literals (in Python 3.6+)
name = "Reiko"
f"She said her name is {name}." # => "She said her name is Reiko"
diff --git a/rust.html.markdown b/rust.html.markdown
index 92794e69..23dcbd4f 100644
--- a/rust.html.markdown
+++ b/rust.html.markdown
@@ -1,5 +1,5 @@
---
-language: rust
+language: Rust
contributors:
- ["P1start", "http://p1start.github.io/"]
filename: learnrust.rs
diff --git a/standard-ml.html.markdown b/standard-ml.html.markdown
index 0ba42f39..9d6b104d 100644
--- a/standard-ml.html.markdown
+++ b/standard-ml.html.markdown
@@ -2,8 +2,8 @@
language: "Standard ML"
filename: standardml.sml
contributors:
- - ["Simon Shine", "http://shine.eu.org/"]
- - ["David Pedersen", "http://lonelyproton.com/"]
+ - ["Simon Shine", "https://simonshine.dk/"]
+ - ["David Pedersen", "https://github.com/davidpdrsn"]
- ["James Baker", "http://www.jbaker.io/"]
- ["Leo Zovic", "http://langnostic.inaimathi.ca/"]
- ["Chris Wilson", "http://sencjw.com/"]
@@ -479,3 +479,4 @@ fun decrement_ret x y = (x := !x - 1; y)
* Follow the Coursera course [Programming Languages](https://www.coursera.org/course/proglang).
* Read *[ML for the Working Programmer](https://www.cl.cam.ac.uk/~lp15/MLbook/pub-details.html)* by Larry C. Paulson.
* Use [StackOverflow's sml tag](http://stackoverflow.com/questions/tagged/sml).
+* Solve exercises on [Exercism.io's Standard ML track](https://exercism.io/tracks/sml).
diff --git a/typescript.html.markdown b/typescript.html.markdown
index 7e857cc0..640be0cd 100644
--- a/typescript.html.markdown
+++ b/typescript.html.markdown
@@ -139,7 +139,7 @@ class Point3D extends Point {
// Overwrite
dist() {
let d = super.dist();
- return Math.sqrt(d * d + this.z * this.z);
+ return Math.sqrt(d() * d() + this.z * this.z);
}
}
diff --git a/vimscript.html.markdown b/vimscript.html.markdown
new file mode 100644
index 00000000..8e023713
--- /dev/null
+++ b/vimscript.html.markdown
@@ -0,0 +1,651 @@
+---
+language: Vimscript
+filename: learnvimscript.vim
+contributors:
+ - ["HiPhish", "http://hiphish.github.io/"]
+---
+
+```vim
+" ##############
+" Introduction
+" ##############
+"
+" Vim script (also called VimL) is the subset of Vim's ex-commands which
+" supplies a number of features one one would expect from a scripting language,
+" such as values, variables, functions or loops. Always keep in the back of
+" your mind that a Vim script file is just a sequence of ex-commands. It is
+" very common for a script to mix programming-language features and raw
+" ex-commands.
+"
+" You can run Vim script directly by entering the commands in command-mode
+" (press `:` to enter command-mode), or you can write them to a file (without
+" the leading `:`) and source it in a running Vim instance (`:source
+" path/to/file`). Some files are sourced automatically as part of your
+" configuration (see |startup|). This guide assumes that you are familiar
+" with ex-commands and will only cover the scripting. Help topics to the
+" relevant manual sections are included.
+"
+" See |usr_41.txt| for the official introduction to Vim script. A comment is
+" anything following an unmatched `"` until the end of the line, and `|`
+" separates instructions (what `;` does in most other languages). References to
+" the manual as surrounded with `|`, such as |help.txt|.
+
+" This is a comment
+
+" The vertical line '|' (pipe) separates commands
+echo 'Hello' | echo 'world!'
+
+" Putting a comment after a command usually works
+pwd " Displays the current working directory
+
+" Except for some commands it does not; use the command delemiter before the
+" comment (echo assumes that the quotation mark begins a string)
+echo 'Hello world!' | " Displays a message
+
+" Line breaks can be escaped by pacing a backslash as the first non-whitespace
+" character on the *following* line. Only works in script files, not on the
+" command line
+echo " Hello
+ \ world "
+
+echo [1,
+ \ 2]
+
+echo {
+ \ 'a': 1,
+ \ 'b': 2
+\}
+
+
+" #######
+" Types
+" #######
+"
+" For an overview of types see |E712|. For an overview of operators see
+" |expression-syntax|
+
+" Numbers (|expr-number|)
+" #######
+
+echo 123 | " Decimal
+echo 0b1111011 | " Binary
+echo 0173 | " Octal
+echo 0x7B | " Hexadecimal
+echo 123.0 | " Floating-point
+echo 1.23e2 | " Floating-point (scientific notation)
+
+" Note that an *integer* number with a leading `0` is in octal notation. The
+" usual arithmetic operations are supported.
+
+echo 1 + 2 | " Addition
+echo 1 - 2 | " Subtraction
+echo - 1 | " Negation (unary minus)
+echo + 1 | " Unary plus (does nothing really, but still legal)
+echo 1 * 2 | " Multiplication
+echo 1 / 2 | " Division
+echo 1 % 2 | " Modulo (remainder)
+
+" Booleans (|Boolean|)
+" ########
+"
+" The number 0 is false, every other number is true. Strings are implicitly
+" converted to numbers (see below). There are two pre-defined semantic
+" constants.
+
+echo v:true | " Evaluates to 1 or the string 'v:true'
+echo v:false | " Evaluates to 0 or the string 'v:false'
+
+" Boolean values can result from comparison of two objects.
+
+echo x == y | " Equality by value
+echo x != y | " Unequality
+echo x > y | " Greater than
+echo x >= y | " Greater than or equal
+echo x < y | " Smaller than
+echo x <= y | " Smaller than or equal
+echo x is y | " Instance identity (lists and dictionaries)
+echo x isnot y | " Instance non-identity (lists and dictionaries)
+
+" Strings are compared based on their alphanumerical ordering
+" echo 'a' < 'b'. Case sensitivity depends on the setting of 'ignorecase'
+"
+" Explicit case-sensitivity is specified by appending '#' (match case) or '?'
+" (ignore case) to the operator. Prefer explicity case sensitivity when writing
+" portable scripts.
+
+echo 'a' < 'B' | " True or false depending on 'ignorecase'
+echo 'a' <? 'B' | " True
+echo 'a' <# 'B' | " False
+
+" Regular expression matching
+echo "hi" =~ "hello" | " Regular expression match, uses 'ignorecase'
+echo "hi" =~# "hello" | " Regular expression match, case sensitive
+echo "hi" =~? "hello" | " Regular expression match, case insensitive
+echo "hi" !~ "hello" | " Regular expression unmatch, use 'ignorecase'
+echo "hi" !~# "hello" | " Regular expression unmatch, case sensitive
+echo "hi" !~? "hello" | " Regular expression unmatch, case insensitive
+
+" Boolean operations are possible.
+
+echo v:true && v:false | " Logical AND
+echo v:true || v:false | " Logical OR
+echo ! v:true | " Logical NOT
+echo v:true ? 'yes' : 'no' | " Ternary operator
+
+
+" Strings (|String|)
+" #######
+"
+" An ordered zero-indexed sequence of bytes. The encoding of text into bytes
+" depends on the option |'encoding'|.
+
+" Literal constructors
+echo "Hello world\n" | " The last two characters stand for newline
+echo 'Hello world\n' | " The last two characters are literal
+echo 'Let''s go!' | " Two single quotes become one quote character
+
+" Single-quote strings take all characters are literal, except two single
+" quotes, which are taken to be a single quote in the string itself. See
+" |expr-quote| for all possible escape sequences.
+
+" String concatenation
+" The .. operator is preferred, but only supported in since Vim 8.1.1114
+echo 'Hello ' . 'world' | " String concatenation
+echo 'Hello ' .. 'world' | " String concatenation (new variant)
+
+" String indexing
+echo 'Hello'[0] | " First byte
+echo 'Hello'[1] | " Second byte
+echo 'Hellö'[4] | " Returns a byte, not the character 'ö'
+
+" Substrings (second index is inclusive)
+echo 'Hello'[:] | " Copy of entire string
+echo 'Hello'[1:3] | " Substring, second to fourth byte
+echo 'Hello'[1:-2] | " Substring until second to last byte
+echo 'Hello'[1:] | " Substring with starting index
+echo 'Hello'[:2] | " Substring with ending index
+echo 'Hello'[-2:] | " Substring relative to end of string
+
+" A negative index is relative to the end of the string. See
+" |string-functions| for all string-related functions.
+
+" Lists (|List|)
+" #####
+"
+" An ordered zero-indexed heterogeneous sequence of arbitrary Vim script
+" objects.
+
+" Literal constructor
+echo [] | " Empty list
+echo [1, 2, 'Hello'] | " List with elements
+echo [1, 2, 'Hello', ] | " Trailing comma permitted
+echo [[1, 2], 'Hello'] | " Lists can be nested arbitrarily
+
+" List concatenation
+echo [1, 2] + [3, 4] | " Creates a new list
+
+" List indexing, negative is relative to end of list (|list-index|)
+echo [1, 2, 3, 4][2] | " Third element
+echo [1, 2, 3, 4][-1] | " Last element
+
+" List slicing (|sublist|)
+echo [1, 2, 3, 4][:] | " Shallow copy of entire list
+echo [1, 2, 3, 4][:2] | " Sublist until third item (inclusive)
+echo [1, 2, 3, 4][2:] | " Sublist from third item (inclusive)
+echo [1, 2, 3, 4][:-2] | " Sublist until second-to-last item (inclusive)
+
+" All slicing operations create new lists. To modify a list in-place use list
+" functions (|list-functions|) or assign directly to an item (see below about
+" variables).
+
+
+" Dictionaries (|Dictionary|)
+" ############
+"
+" An unordered sequence of key-value pairs, keys are always strings (numbers
+" are implicitly converted to strings).
+
+" Dictionary literal
+echo {} | " Empty dictionary
+echo {'a': 1, 'b': 2} | " Dictionary literal
+echo {'a': 1, 'b': 2, } | " Trailing comma permitted
+echo {'x': {'a': 1, 'b': 2}} | " Nested dictionary
+
+" Indexing a dictionary
+echo {'a': 1, 'b': 2}['a'] | " Literal index
+echo {'a': 1, 'b': 2}.a | " Syntactic sugar for simple keys
+
+" See |dict-functions| for dictionary manipulation functions.
+
+
+" Funcref (|Funcref|)
+" #######
+"
+" Reference to a function, uses the function name as a string for construction.
+" When stored in a variable the name of the variable has the same restrictions
+" as a function name (see below).
+
+echo function('type') | " Reference to function type()
+" Note that `funcref('type')` will throw an error because the argument must be
+" a user-defined function; see further below for defining your own functions.
+echo funcref('type') | " Reference by identity, not name
+" A lambda (|lambda|) is an anonymous function; it can only contain one
+" expression in its body, which is also its implicit return value.
+echo {x -> x * x} | " Anonymous function
+echo function('substitute', ['hello']) | " Partial function
+
+
+" Regular expression (|regular-expression|)
+" ##################
+"
+" A regular expression pattern is generally a string, but in some cases you can
+" also use a regular expression between a pair of delimiters (usually `/`, but
+" you can choose anything).
+
+" Substitute 'hello' for 'Hello'
+substitute/hello/Hello/
+
+
+" ###########################
+" Implicit type conversions
+" ###########################
+"
+" Strings are converted to numbers, and numbers to strings when necessary. A
+" number becomes its decimal notation as a string. A string becomes its
+" numerical value if it can be parsed to a number, otherwise it becomes zero.
+
+echo "1" + 1 | " Number
+echo "1" .. 1 | " String
+echo "0xA" + 1 | " Number
+
+" Strings are treated like numbers when used as booleans
+echo "true" ? 1 : 0 | " This string is parsed to 0, which is false
+
+" ###########
+" Variables
+" ###########
+"
+" Variables are bound within a scope; if no scope is provided a default is
+" chosen by Vim. Use `:let` and `:const` to bind a value and `:unlet` to unbind
+" it.
+
+let b:my_var = 1 | " Local to current buffer
+let w:my_var = 1 | " Local to current window
+let t:my_var = 1 | " Local to current tab page
+let g:my_var = 1 | " Global variable
+let l:my_var = 1 | " Local to current function (see functions below)
+let s:my_var = 1 | " Local to current script file
+let a:my_arg = 1 | " Function argument (see functions below)
+
+" The Vim scope is read-only
+echo v:true | " Special built-in Vim variables (|v:var|)
+
+" Access special Vim memory like variables
+let @a = 'Hello' | " Register
+let $PATH='' | " Environment variable
+let &textwidth = 79 | " Option
+let &l:textwidth = 79 | " Local option
+let &g:textwidth = 79 | " Global option
+
+" Access scopes as dictionaries (can be modified like all dictionaries)
+" See the |dict-functions|, especially |get()|, for access and manipulation
+echo b: | " All buffer variables
+echo w: | " All window variables
+echo t: | " All tab page variables
+echo g: | " All global variables
+echo l: | " All local variables
+echo s: | " All script variables
+echo a: | " All function arguments
+echo v: | " All Vim variables
+
+" Constant variables
+const x = 10 | " See |:const|, |:lockvar|
+
+" Function reference variables have the same restrictions as function names
+let IsString = {x -> type(x) == type('')} | " Global: capital letter
+let s:isNumber = {x -> type(x) == type(0)} | " Local: any name allowed
+
+" When omitted the scope `g:` is implied, except in functions, there `l:` is
+" implied.
+
+
+" Multiple value binding (list unpacking)
+" #######################################
+"
+" Assign values of list to multiple variables (number of items must match)
+let [x, y] = [1, 2]
+
+" Assign the remainer to a rest variable (note the semicolon)
+let [mother, father; children] = ['Alice', 'Bob', 'Carol', 'Dennis', 'Emily']
+
+
+" ##############
+" Flow control
+" ##############
+
+" Conditional (|:if|, |:elseif|, |:else|, |:endif|)
+" ###########
+"
+" Conditions are set between `if` and `endif`. They can be nested.
+
+let condition = v:true
+
+if condition
+ echo 'First condition'
+elseif another_condition
+ echo 'Second condition'
+else
+ echo 'Fail'
+endif
+
+" Loops (|:for|, |:endfor|, |:while|, |:endwhile|, |:break|, |:continue|)
+" #####
+"
+" Two types of loops: `:for` and `:while`. Use `:continue` to skip to the next
+" iteration, `:break` to break out of the loop.
+
+" For-loop (|:for|, |:endfor|)
+" ========
+"
+" For-loops iterate over lists and nothing else. If you want to iterate over
+" another sequence you need to use a function which will create a list.
+
+" Iterate over a list
+for person in ['Alice', 'Bob', 'Carol', 'Dennis', 'Emily']
+ echo 'Hello ' .. person
+endfor
+
+" Iterate over a nested list by unpacking it
+for [x, y] in [[1, 0], [0, 1], [-1, 0], [0, -1]]
+ echo 'Position: x =' .. x .. ', y = ' .. y
+endfor
+
+" Iterate over a range of numbers
+for i in range(10, 0, -1) " Count down from 10
+ echo 'T minus' .. i
+endfor
+
+" Iterate over the keys of a dictionary
+for symbol in keys({'π': 3.14, 'e': 2.71})
+ echo 'The constant ' .. symbol .. ' is a transcendent number'
+endfor
+
+" Iterate over the values of a dictionary
+for value in values({'π': 3.14, 'e': 2.71})
+ echo 'The value ' .. value .. ' approximates a transcendent number'
+endfor
+
+" Iterate over the keys and values of a dictionary
+for [symbol, value] in items({'π': 3.14, 'e': 2.71})
+ echo 'The number ' .. symbol .. ' is approximately ' .. value
+endfor
+
+" While-loops (|:while|, |:endwhile|)
+
+let there_yet = v:true
+while !there_yet
+ echo 'Are we there yet?'
+endwhile
+
+
+" Exception handling (|exception-handling|)
+" ##################
+"
+" Throw new exceptions as strings, catch them by pattern-matching a regular
+" expression against the string
+
+" Throw new exception
+throw "Wrong arguments"
+
+" Guard against an exception (the second catch matches any exception)
+try
+ source path/to/file
+catch /Cannot open/
+ echo 'Looks like that file does not exist'
+catch /.*/
+ echo 'Something went wrong, but I don't know what'
+finally
+ echo 'I'm done trying'
+endtry
+
+
+" ##########
+" Functions
+" ##########
+
+" Defining functions (|:function|, |:endfunction|)
+" ##################
+
+" Unscoped function names have to start with a capital letter
+function! AddNumbersLoudly(x, y)
+ " Use a: scope to access arguments
+ echo 'Adding' .. a:x .. 'and' .. a:y | " A side effect
+ return a:x + a:y | " A return value
+endfunction
+
+" Scoped function names may start with a lower-case letter
+function! s:addNumbersLoudly(x, y)
+ echo 'Adding' .. a:x .. 'and' .. a:y
+ return a:x + a:y
+endfunction
+
+" Without the exclamation mark it would be an error to re-define a function,
+" with the exclamation mark the new definition can replace the old one. Since
+" Vim script files can be reloaded several times over the course of a session
+" it is best to use the exclamation mark unless you really know what you are
+" doing.
+
+" Function definitions can have special qualifiers following the argument list.
+
+" Range functions define two implicit arguments, which will be set to the range
+" of the ex-command
+function! FirstAndLastLine() range
+ echo [a:firstline, a:lastline]
+endfunction
+
+" Prints the first and last line that match a pattern (|cmdline-ranges|)
+/^#!/,/!#$/call FirstAndLastLine()
+
+" Aborting functions, abort once error occurs (|:func-abort|)
+function! SourceMyFile() abort
+ source my-file.vim | " Try sourcing non-existing file
+ echo 'This will never be printed'
+endfunction
+
+" Closures, functions carrying values from outer scope (|:func-closure|)
+function! MakeAdder(x)
+ function! Adder(n) closure
+ return a:n + a:x
+ endfunction
+ return funcref('Adder')
+endfunction
+let AddFive = MakeAdder(5)
+echo AddFive(3) | " Prints 8
+
+" Dictionary functions, poor man's OOP methods (|Dictionary-function|)
+function! Mylen() dict
+ return len(self.data) | " Implicit variable self
+endfunction
+let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
+echo mydict.len()
+
+" Alternatively, more concise
+let mydict = {'data': [0, 1, 2, 3]}
+function! mydict.len()
+ return len(self.data)
+endfunction
+
+" Calling functions (|:call|)
+" #################
+
+" Call a function for its return value, and possibly for its side effects
+let animals = keys({'cow': 'moo', 'dog': 'woof', 'cat': 'meow'})
+
+" Call a function for its side effects only, ignore potential result
+call sign_undefine()
+
+" The call() function calls a function reference and passes parameters as a
+" list, and returns the function's result.
+echo call(function('get'), [{'a': 1, 'b': 2}, 'c', 3]) | " Prints 3
+
+" Recall that Vim script is embedded within the ex-commands, that is why we
+" cannot just call a function directly, we have to use the `:call` ex-command.
+
+" Function namespaces (|write-library-script|, |autoload|)
+" ###################
+
+" Must be defined in autoload/foo/bar.vim
+" Namspaced function names do not have to start with a capital letter
+function! foo#bar#log(value)
+ echomsg value
+endfunction
+
+call foo#bar#log('Hello')
+
+
+" #############################
+" Frequently used ex-commands
+" #############################
+
+
+" Sourcing runtime files (|'runtimepath'|)
+" ######################
+
+" Source first match among runtime paths
+runtime plugin/my-plugin.vim
+
+
+" Defining new ex-commands (|40.2|, |:command|)
+" ########################
+
+" First argument here is the name of the command, rest is the command body
+command! SwapAdjacentLines normal! ddp
+
+" The exclamation mark works the same as with `:function`. User-defined
+" commands must start with a capital letter. The `:command` command can take a
+" number of attributes (some of which have their own parameters with `=`), such
+" as `-nargs`, all of them start with a dash to set them apart from the command
+" name.
+
+:command -nargs=1 Error echoerr <args>
+
+
+" Defining auto-commands (|40.3|, |autocmd|, |autocommand-events|)
+" ######################
+
+" The arguments are "events", "patterns", rest is "commands"
+autocmd BufWritePost $MYVIMRC source $MYVIMRC
+
+" Events and patterns are separated by commas with no space between. See
+" |autocmd-events| for standard events, |User| for custom events. Everything
+" else are the ex-commands which will be executed.
+
+" Auto groups
+" ===========
+"
+" When a file is sourced multiple times the auto-commands are defined anew,
+" without deleting the old ones, causing auto-commands to pile up over time.
+" Use auto-groups and the following ritual to guard against this.
+
+augroup auto-source | " The name of the group is arbitrary
+ autocmd! | " Deletes all auto-commands in the current group
+ autocmd BufWritePost $MYVIMRC source $MYVIMRC
+augroup END | " Switch back to default auto-group
+
+" It is also possible to assign a group directly. This is useful if the
+" definition of the group is in one script and the definition of the
+" auto-command is in another script.
+
+" In one file
+augroup auto-source
+ autocmd!
+augroup END
+
+" In another file
+autocmd auto-source BufWritePost $MYVIMRC source $MYVIMRC
+
+" Executing (run-time macros of sorts)
+" ####################################
+
+" Sometimes we need to construct an ex-command where part of the command is not
+" known until runtime.
+
+let line = 3 | " Line number determined at runtime
+execute line .. 'delete' | " Delete a line
+
+" Executing normal-mode commands
+" ##############################
+"
+" Use `:normal` to play back a sequence of normal mode commands from the
+" command-line. Add an exclamation mark to ignore user mappings.
+
+normal! ggddGp | " Transplant first line to end of buffer
+
+" Window commands can be used with :normal, or with :wincmd if :normal would
+" not work
+wincmd L | " Move current window all the way to the right
+
+
+" ###########################
+" Frequently used functions
+" ###########################
+
+" Feature check
+echo has('nvim') | " Running Neovim
+echo has('python3') | " Support for Python 3 plugins
+echo has('unix') | " Running on a Unix system
+echo has('win32') | " Running on a Windows system
+
+
+" Test if something exists
+echo exists('&mouse') | " Option (exists only)
+echo exists('+mouse') | " Option (exists and works)
+echo exists('$HOSTNAME') | " Environment variable
+echo exists('*strftime') | " Built-in function
+echo exists('**s:MyFunc') | " User-defined function
+echo exists('bufcount') | " Variable (scope optional)
+echo exists('my_dict["foo"]') | " Variable (dictionary entry)
+echo exists('my_dict["foo"]') | " Variable (dictionary entry)
+echo exists(':Make') | " Command
+echo exists("#CursorHold") | " Auto-command defined for event
+echo exists("#BufReadPre#*.gz") | " Event and pattern
+echo exists("#filetypeindent") | " Auto-command group
+echo exists("##ColorScheme") | " Auto-commnand supported for event
+
+" Various dynamic values (see |expand()|)
+echo expand('%') | " Current file name
+echo expand('<cword>') | " Current word under cursor
+echo expand('%:p') | " Modifier are possible
+
+" Type tests
+echo type(my_var) == type(0) | " Number
+echo type(my_var) == type('') | " String
+echo type(my_var) == type([]) | " List
+echo type(my_var) == type({}) | " Dictionary
+echo type(my_var) == type(function('type')) | " Funcref
+
+" Format strings
+echo printf('%d in hexadecimal is %X', 123, 123)
+
+
+" #####################
+" Tricks of the trade
+" #####################
+
+" Source guard
+" ############
+
+" Prevent a file from being source multiple times; users can set the variable
+" in their configuration to prevent the plugin from loading at all.
+if exists('g:loaded_my_plugin')
+ finish
+endif
+let g:loaded_my_plugin = v:true
+
+" Default values
+" ##############
+
+" Get a default value: if the user defines a variable use it, otherwise use a
+" hard-coded default. Uses the fact that a scope is also a dictionary.
+let s:greeting = get(g:, 'my_plugin_greeting', 'Hello')
+```