After learning what the basic data types are, the next step is to learn how to combine them together to start writing a basic program. A basic program consists of conditionals and loops.
In this chapter, you will learn how to use Vimscript data types to write conditionals and loops.
Recall that strings are coerced into numbers in an arithmetic expression. Here Vim also coerces strings into numbers in an equality expression. "5foo" is coerced into 5 (truthy):
The `=~` operator performs a regex match against the given string. In the example above, `str =~ "hearty"` returns true because `str`*contains* the "hearty" pattern. You can always use `==` and `!=`, but using them will compare the expression against the entire string. `=~` and `!~` are more flexible choices.
```
echo str == "hearty"
" returns false
echo str == "hearty breakfast"
" returns true
```
Let's try this one. Note the uppercase "H":
```
echo str =~ "Hearty"
" true
```
It returns true even though "Hearty" is capitalized. Interesting... It turns out that my Vim setting is set to ignore case (`set ignorecase`), so when Vim checks for equality, it uses my Vim setting and ignores the case. If I were to turn off ignore case (`set noignorecase`), the comparison now returns false.
If you are writing a plugin for others, this is a tricky situation. Does the user use `ignorecase` or `noignorecase`? You definitely do *not* want to force your users to change their ignore case option. So what do you do?
For example, the plugin [vim-signify](https://github.com/mhinz/vim-signify) uses a different installation method depending on your Vim settings. Below is the installation instruction from their `readme`, using the `if` statement:
Vim has a ternary expression for a one-liner case analysis:
```
{predicate} ? expressiontrue : expressionfalse
```
For example:
```
echo 1 ? "I am true" : "I am false"
```
Since 1 is truthy, Vim echoes "I am true". Suppose you want to conditionally set the `background` to dark if you are using Vim past a certain hour. Add this to vimrc:
```
let &background = strftime("%H") <18?"light":"dark"
```
`&background` is the `'background'` option in Vim. `strftime("%H")` returns the current time in hours. If it is not yet 6 PM, use a light background. Otherwise, use a dark background.
## Or
The logical "or" (`||`) works like many programming languages.
```
{Falsy expression} || {Falsy expression} false
{Falsy expression} || {Truthy expression} true
{Truthy expression} || {Falsy expression} true
{Truthy expression} || {Truthy expression} true
```
Vim evaluates the expression and return either 1 (truthy) or 0 (falsy).
```
echo 5 || 0
" returns 1
echo 5 || 5
" returns 1
echo 0 || 0
" returns 0
echo "foo5" || "foo5"
" returns 0
echo "5foo || foo5"
" returns 1
```
If the current expression evaluates to truthy, the subsequent expression won't be evaluated.
```
let one_dozen = 12
echo one_dozen || two_dozen
" returns 1
echo two_dozen || one_dozen
" returns error
```
Note that `two_dozen` is never defined. The expression `one_dozen || two_dozen` doesn't throw any error because `one_dozen` is evaluated first found to be truthy, so Vim doesn't evaluate `two_dozen`.
## And
The logical "and" (`&&`) is the complement of the logical or.
Unlike "or", "and" will evaluate the subsequent expression after it reaches the first falsy expression. It will continue to evaluate the subsequent truthy expressions until the end or when it sees the first falsy expression.
To get the content of the current line to the last line:
```
let current_line = line(".")
let last_line = line("$")
while current_line <= last_line
echo getline(current_line)
let current_line += 1
endwhile
```
## Error Handling
Often your program doesn't run the way you expect it to. As a result, it throws you for a loop (pun intended). What you need is a proper error handling.
The `continue` method is similar to `break`, where it is invoked during a loop. The difference is that instead of breaking out of the loop, it just skips that current iteration.
Suppose you have the same text but instead of `break`, you use `continue`:
```
let line = 0
let last_line = line("$")
let total_word = ""
while line <= last_line
let line += 1
let line_text = getline(line)
if line_text =~# "donut"
continue
endif
echo line_text
let total_word .= line_text . " "
endwhile
echo total_word
```
This time it returns `one two three four five`. It skips the line with the word "donut", but the loop continues.
If you notice from the list above, there is a catch for interrupt. Inside a `try` block, an interrupt is considered a catchable error.
```
try
catch /^Vim:Interrupt$/
sleep 100
endtry
```
In your vimrc, if you use a custom colorscheme, like [gruvbox](https://github.com/morhetz/gruvbox), and you accidentally delete the colorscheme directory but still have the line `colorscheme gruvbox` in your vimrc, Vim will throw an error when you `source` it. To fix this, I added this in my vimrc:
```
try
colorscheme gruvbox
catch
colorscheme default
endtry
```
Now if you `source` vimrc without `gruvbox` directory, Vim will use the `colorscheme default`.
In the previous chapter, you learned about Vim basic data types. In this chapter, you learned how to combine them to write basic programs using conditionals and loops. These are the building blocks of programming.