Neovim

Scientific Computing

Author

Prof. Calvin

Why Neovim?

On Neovim

  • Neovim is free,
  • Neovim is very widely available,
  • Neovim is highly customizable,
  • Neovim is stable, year-on-year,
  • and Neovim is quite powerful.

Watch more

Why not Neovim?

  • Modal - it is not a “What you see is what you get” (WYSIWYG) editor like MS Word, Google Docs, Notepad, or VS Code
  • Terminal-based - it is used within the terminal and not often as a stand-alone program.
  • Steep-learning curve - students generally find it difficult to get started, though it is widely preferred by experienced users

Running Example

Diving In

  • Taking Neovim as a given, we’ll:
    • Continue the piecewise functions example
    • Touch on Python and the terminal in the context of Neovim
    • Introduce Neovim modes, motions, and operators.
  • Spoilers for the last exercise!

Exercise

  • Write function
  • def single_tax(pay):
  • Return tax cost.
    • Return not print!
  • Bonus: Also write single_tax_rate which returns the percent tax rate at some income level.
Rate From
10% 0
15% 9275
25% 37650
28% 91150
33% 190150
35% 413350
39.6% 415050

Solutions

def single_tax(pay):
    tax = 0
    if pay > 415050:
        tax += (pay - 415050) * .396
        pay = 415050
    if pay > 413350:
        tax += (pay - 413350) * .35
        pay = 413350
    if pay > 190150:
        tax += (pay - 190150) * .33
        pay = 190150
    if pay > 91150:
        tax += (pay - 91150) * .28
        pay = 91150
    if pay > 37650:
        tax += (pay - 37650) * .25
        pay = 37650
    if pay > 9275:
        tax += (pay - 9275) * .15
        pay = 9275
    return tax + pay * .1
def single_tax(pay):
    tax_policy = [
        [415050, .396], 
        [413350, .35],
        [190150, .33],
        [91150, .28],
        [37650, .25],
        [9275, .15]
    ]
    tax = 0
    for bracket in tax_policy:
        if pay > bracket[0]:
            tax += (pay - bracket[0]) * bracket[1]
            pay = bracket[0]
    return tax + pay * .1

Tedious to Type

PS C:\Users\calvin> python
Python 3.12.5 (tags/v3.12.5:ff3bc82, Aug  6 2024, 20:45:27) [MSC v.1940 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> def single_tax(pay):
...     tax_policy = [
...         [415050, .396],
...         [413350, .35],
...         [190150, .33],
...         [91150, .28],
...         [37650, .25],
...         [9275, .15]
...     ]
...     tax = 0
...     for bracket in tax_policy:
...         if pay > bracket[0]:
...             tax += (pay - bracket[0]) * bracket[1]
...             pay = bracket[0]
...     return tax + pay * .1
...
>>> single_tax(400000)
115529.25
>>>

Instead: .py files

  • Python has an associated file type, the .py file.
    • Similar to .png (portable network graphic) for images
    • Similar to .pdf (portable document format) for papers

Test-based

  • The .py file is much like a .txt file in that:
    • It is a small, lightweight file containing only typed characters.
    • It can be opened, edited, and viewed in many editors.
  • The .py file can save typed code to be used within python.

Enter Neovim

  • Neovim is a great way to edit text.
Give it a shot!

Students often object to switching from WYSIWYG editors but:

  • Many students know no other way to write text-based files, and
  • We’ve ample time this term to properly explore Neovim

Be patient, but also work hard!

Getting Neovim

Installation

  • We go to the offial webpage to get an installer for our computer:
  • Neovim offers a few more installation options than you may be used to.
  • I recommend…

Install from download

Downloads are available on the Releases page.

Terminal

  • On MS Windows
    • I press Windows key, type “terminal” then press enter.
  • On MacOS
    • I open Launchpad, type “terminal” then press enter.

MacOS

Windows

Expression evaluation

  • Returning to the terminal, we can type at the “prompt”.
  • On MacOS, perhaps a line that begins with $ and a flashing cursor
  • On Window, perhaps PS C:\Users\calvin>
    • PS stands for “powershell” - more latter.
    • C:\Users\calvin is the name of a folder - more latter
    • > is the prompt, with a flashing cursor.

Run Neovim

In the following examples, I remove line numbers to denote they are not Python code snippets.

  • On MacOS, type nvim
MacOS
$ nvim
  • On Windows, type nvim
Windows
PS C:\Users\calvin> nvim
  • On both, press the ↵ᴇɴᴛᴇʀ key.

See Neovim

  • You’ll see something like this:
                  NVIM v0.11.1

  Nvim is open source and freely distributable
           https://neovim.io/#chat

 type :help nvim<Enter>               if you are new!
 type :checkhealth<Enter>             to optimize Nvim
 type :q<Enter>                       to exit
 type :help<Enter>                    for help

type :help news<Enter> to see changes in v0.11

        Help poor children in Uganda!
 type :help iccf<Enter>               for information

Modes

Modality

  • nvim is a modal text editor
  • By default, typed characters will not appear in the document.
  • Rather, by default, we being in command mode.
  • We won’t worry about that too much, but the first command to learn is
i
  • i for insert

Insert Mode

  • By the way, you should see -- INSERT -- at the bottom of the terminal window.
  • Insert mode is not unlike WYSIWYG
  • Use it prolificly until you are more comfortable.
  • Navigate with arrow keys or (depending on system) mouse
  • For now, let’s copy paste in the piecewise function.

Piecewise

  • For me, basic copy/paste commands like:
    • ctrl/cmd+c, ctrl/cmd+v
    • rclick->menu->copy
  • Worked amicably in i insert mode
pw.py
def piecewise(x):
    if (x < 4):
        return 9 * x ** 2 + 5
    elif (4 <= x <= 8):
        return 9
    elif (x > 8):
        return 2 - x
  • For .py files I’ll include line numbers but add a filename on top.

Command Mode

  • Having written some text, we now need to save it to a file.
  • Press the “ESC” (Escape) key to return to command mode
  • Your cursor will move the bottom of the terminal, where -- INSERT -- was

Remember!

Remember to press escape!
  • In nvim examples today, it will not always be easy to make a note of when to press escape!
  • As a rule, use escape before anytime you try to do something (exit, save)
  • These “do things” usually are : prefixed
  • Press i to get back to typing (insert mode)

Issuing commands

  • After :w (write) and the name of the file
  • Include the .py ending!
  • I wrote:
:w pw.py

Save and Quit

  • You can always use :w to save while working.
  • Make any edits you make need to make - a missed paren perhaps.
  • Then both save and exit nvim with :x
    • This special command saves the file and exits nvim
  • You will return to the command line you started with, likely without incident.
    • But there will now be a new file you can use!

Scripting

Back in Terminal

  • On MacOS, you’ll see nvim and a new prompt
MacOS
$ nvim
$
  • On Windows, the same
Windows
PS C:\Users\calvin> nvim
PS C:\Users\calvin> 

Aside: Terminal Commands

  • Like Python and Neovim, there are also terminal commands!
    • Two are python/python3 and nvim!
  • Another is ls, which stands for “list”
    • This command has been around so long, it is from an era when commands were shorter to save precious computer memory!
  • It “lists” local files, and can list them by name!

Aside: Using ls

  • Try out this command, to see that you have a pw.py file!
$ ls pw.py
  • What do you see (different on Windows and MacOS)?

Checkpoint

  • If you do not have a pw.py file, stop here until you have one!
Windows
PS C:\Users\calvin> ls pw.py


    Directory: C:\Users\cd-desk


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         5/20/2025   3:21 PM            151 pw.py
MacOS
$ ls pw.py
pw.py
$

.py files

  • There are two common ways to use .py files

  • I believe the most common is via import

  • To begin, at the command line, start Pythoni

  • On Windows, type python

Windows
PS C:\Users\calvin> python
  • On MacOS, type python3
MacOS
$ python3
  • On both, press the ↵ᴇɴᴛᴇʀ key.

See Python

  • You’ll see something like this:
  • Take note of the prompt!
  • >>>
  • Those three are how you know it is Python, and not the Terminal, that you are working in.

Import

  • Versus last time, we now have a piecewise function written in a .py file we can reference.
  • To do so, we:
    • Type import followed by a space
    • Type the filename less the .py extension
    • It should look like this:

Modules

  • import pw will introduce a new variable to Python to which we can refer by name (pw)
  • It is of a new type for us, “module”
  • Modules correspond to .py files!
  • (The from will look different on different computers)

Importing Functions

  • We can use functions inside modules in a few ways.
  • First, we can use the module name (pw) followed by a dot or period (.) followed by the name of the function.

Renaming Functions

  • Second, we can just use single equals assignment

Using from

  • Third, we can use the from keyword in our import.
    • This is by far preferred (it is more clear)
  • I only show you the other methods to make it clear what this method is doing.

Exit Python

  • Oftentimes, we’ll run a bit of Python then want to go back to the command line to use nvim
exit()

You can exit the Python >>> prompt back to Windows > or MacOS $ at any time:

  • Use exit()
  • Use quit()
  • Use ctrl/cmd+z

Practice starting and leaving Python a few times!

Using Terminal

Command Line Utilities

I find the following tedious:

  1. nvim
  2. Write some code
  3. :w somefile.py
  4. ESC then :x
  5. python
  6. from somefile import somefunction
  7. somefunction(x)
  8. exit()

Alternative

  • We will instead:
    • Show how to how run script files
    • Show how to provide input to script files

Hello, Terminal

  • To begin, we will do terminal “Hello, World!”
  • I use nvim hi.py to create and open a new file named hi.py
  • Then I write:
hi.py
print("Hello, terminal!")

Running Scripts

  • I save and exit via :x
  • Then I run the Python script via python hi.py
  • For me, it looks like this:

What happened?

  • Basically, Python runs the code written in the file as if it were entered at the prompts.
  • It then provides the expected print statements.
  • We can run multiple times without rewriting the script.

Piecewise Script

  • Say we wish to find the piecewise results from the prior lecture.
  • nvim pw.py
  • I use G to jump to the end of the file
    • This is a “vim motion”
  • I use i to change into insert mode, and add:
pw.py
for e in [-1, 4, 5, 8, 11]:
    print([e, piecewise(e)])
  • Save and exit with (escape then) :x

Test it

Using input

  • Fortunately, Python has a built-in function that is (basically) the opposite of print
  • Within the terminal, run python
  • Then within Python, call input()
  • What happens?

What if?

  • We want to be able to check values without either
    • Opening python and doing an import, or
    • Opening nvim and editing the list
  • We can do that by providing input
    • We write a script that expects us to type in some information!

Python input

  • Python helpfully has an input that is basically the opposite of print.
  • input
  • It is easiest to learn by trying it out!

Providing input

  • Open Python
  • Call the function input()
  • Type something - anything - then press enter.
  • The input() function returns the text that is typed in

Script input

  • Let’s make a little script to try out input()
reply.py
x = input()
print(x)
  • Think about the steps to create and run this file!

Example

  • Try it out!

Return v. Print

Print, Not Return
  • To see the results of some expression or computation other work in the terminal, we must print within scripts.
  • print() for terminal
  • return within Python

Datatypes

A Wrinkle

  • There’s one little problem here.
  • Let’s update pw.py to to run on input() and see what happens.
pw.py
def piecewise(x):
    if (x < 4):
        return 9 * x ** 2 + 5
    elif (4 <= x <= 8):
        return 9
    elif (x > 8):
        return 2 - x

x = input()
y = piecewise(x)
print(y)

Uh oh!

  • I see the following:

Recall

  • We worked with different types last time:
    • Think about what is happening here
[type(1), type(1 == 2), type([1,2]), type({1,2})]
[int, bool, list, set]
  • The type of input() is a new type - str
    • Short for “string” - as in string of characters
type("Hello, world!")
str

Casting

  • Changing data of one type (like str) into another (like int) is called casting
  • In Python, to cast we use the name of the type we want as a function on the value in the type we don’t want.
  • Easy to try within python

Try it

  • Python shows something is a string by enclosing it within quote marks ''

Fix pw.py

pw.py
def piecewise(x):
    if (x < 4):
        return 9 * x ** 2 + 5
    elif (4 <= x <= 8):
        return 9
    elif (x > 8):
        return 2 - x

x = input()
y = int(x)
z = piecewise(y)
print(z)

Use it

Exercise

Income Tax

  • We’ll return to the income tax example, and
  • Add a wrinkle.
  • Here’s an income tax solution:
Code
def single_tax(pay):
    tax_policy = [
        [415050, .396], 
        [413350, .35],
        [190150, .33],
        [91150, .28],
        [37650, .25],
        [9275, .15]
    ]
    tax = 0
    for bracket in tax_policy:
        if pay > bracket[0]:
            tax += (pay - bracket[0]) * bracket[1]
            pay = bracket[0]
    return tax + pay * .1

Arguments

  • There is one other way to specify what you want a script to do.
  • Command line arguments
  • This is my favorite way (simpliest to use)
    • (Bit harder to write)
  • It is based on the Python sys module

sys

  • Create and try out the following file:
args.py
import sys

print(sys.argv)
  • What does it do?

‘argv’

  • ‘argv’ stands for “argument vector”
  • You may have noticed it is a list
    • Other programming languages sometimes call lists vectors
    • Computer systems often call lists vectors
    • Python follows this convention

Add an arg

  • What happens if you do this?

Remember!

Lists begin with zero!
  • When using argv, recall it is a Python list!
  • The initial element - what we would often call first - is at position zero
  • Would would print only this element as follows:
args.py
import sys

print(sys.argv[0])

Exercise

  • Create a file tax.py
  • Have it accept an income as a command line argument
  • Have it print a tax cost at command line.
  • Here’s an example how it should work!

Challenge Problem

  • Accept two command line arguments
    • Income, and
    • One of ['single', 'married', 'separate', 'head']
  • Print the tax regardless of “single-ness”

Solution

Code
import sys

print(single_tax(int(sys.argv[1])))