10. Visual Studio Code and Other Tools#
Contents
While Jupyter notebooks are a great way to get started with the language, eventually you will want to use more powerful tools. Visual Studio Code (VS Code) in particular, is the most popular open source editor for programming - with a huge set of extensions and strong industry support.
While you can use source code control, run terminals and the REPL (“Read-Evaluate-Print Loop”) without VS Code, we will concentrate on using it as a full IDE for all of these features.
See Modern Julia Workflows for alternative approaches.
10.1. Installing VS Code#
To install VS Code and the Julia Extension,
First, ensure you followed the instructions for setting up Julia on your local computer.
In particular, ensure you did the initial VS Code setup
Install VS Code for your platform and open it
See the Julia VS Code Documentation for more details.
If you have done a typical Julia installation, then this may be all that is needed and no configuration may be necessary. However, if you have installed Julia in a non-standard location you may need to manually set the executable path. See here for instructions if it errors when starting Julia terminals.
Tip
“Open in Code” on MacOS and Linux VS Code supports the “Open with Code” action in File Explorer if chosen during the installation. This is convenient, but not necessary. To support it on MacOS you need to install a Automator script or separate package. Similarly, see here for support on linux.
While the general VS Code documentation is excellent, we will review a few of the key concepts directly. In addition, see here for other useful extensions when using VS Code not directly connected to these lectures.
10.1.1. Optional Extensions and Settings#
Open the settings with > Preferences: Open User Settings
(see above for opening the command palette with <Ctrl-Shift-P>
).
As a few optional suggestions for working with the settings,
In the settings, search for
Tab Size
and you should findEditor: Tab Size
which you can modify to 4.Search for
quick open
and changeWorkbench > Editor: Enable Preview from Quick Open
and consider setting it to false, though this is a matter of personal taste.If you are on Windows, search for
eol
and changeFiles: Eol
to be\n
.While it is a personal taste, consider enabling the bracket colorizer by finding the
bracketPairColorization
setting.
A key feature of VS Code is that it can synchronize your extensions and settings across all of your computers, and even when used in-browser (e.g. with GitHub CodeSpaces). To turn on,
Ensure you have a GitHub account, which will be useful for further lectures
Choose
Turn On Settings Sync...
in the gear icon at the bottom of the screen
You can stick with all of the defaults, and read more in the instructions
10.1.2. Integrated Terminals in VS Code#
A key benefit of VS Code is that you can use terminals and command-line interfaces directly within the editor, and starting in the convenient location relative to an opened project.
Furthermore, in the case of julia (and other languages such as python) this will activate the project automatically. See the documentation for more details.
You can open the terminal panel with > View: Toggle Terminal
, typing Ctrl+`
, or by clicking on the list of warnings and errors bottom bar in VS Code. If no existing terminal exists, it will create a new one.
10.2. Using VS Code with Julia#
The documentation for the VS Code extension provides many examples:
In addition, there are excellent youtube videos about provide more background. For example, Package Development in VSCode shows advanced features.
10.2.1. Hello World#
To walk through a simple, but complete example.
Create a new directory on your computer, for example hello_world
and then open VS Code in that folder This can be done several ways,
Within a terminal on your operating system, navigate that directory and type
code .
On Windows, right click on the folder and choose
Open with Code
- trusting the authors as required on opening the folder.In the VS Code Menu, choose
File/Open Folder...
Next, in the left hand panel, under HELLO_WORLD
, right click and choose New File
and create as hello.jl
. The screen should look something like
Type some code as such f(x) = x + 1
into the file, into the .jl
file, save it, and while your mouse curser is on the line of code do <Shift-Enter>
. If a julia REPL wasn’t already started, it will be started and the code will be run within its kernel
At this point, the function is available for use within either the code or the REPL. You can get inline results by adding more code to the file and executing each line with <Shift-Enter>
.
That code is also accessible within the REPL. Executing the function there,
Because the REPL and the files are synchronized, you can modify functions and simple choose <shift-Enter>
to update their definitions before analyzing the results in the REPL or in the file itself.
10.2.2. Adding Packages#
Next we will go through simple use of the plotting and package management.
Note
VS Code typically activates the current project correctly. However, when choosing to enter the package mode, if the prompt changes to (@v1.8) pkg>
rather than (hello_world) pkg >
then you will need to manually activate the project. In that case, ensure that you are in the correct location and choose ] activate .
.
You can always see the current package location and details with ] st
. See Julia Environments for more details.
The REPL. First, type ]
to enter the package management mode, then add Plots
. Depending on whether you have done similar operations before, this may download a lot of dependencies. See below for an example
Crucially, you will notice that two new files are created. Project.toml
and Manifest.toml
. These provide a snapshot of all of the packages used in this particular project.
Add code in the .jl
file for a simple plot, and it will be shown on a separate pane
To exit package management mode and return to the REPL, type Ctrl+C
. To then go from the REPL back to the VS Code terminal, type Ctrl+D
.
10.2.3. Executing Files#
First we will reorganize our file so that it is a set of functions with a call at the end rather than a script. Replace the code with
using Plots, Random
f(x) = x + 1
function plot_results()
x = 1:5
y = f.(x)
plot(x, y)
print(y)
end
# execute main function
plot_results()
While it is fine to use scripts with code not organized in functions for exploration, you will want to organize any serious computations inside of a function. While this may not matter for every problem, this will let the compiler avoid global variables and highly optimize the results.
Note
The behavior of global variables accessed in loops in the REPL
, Debugger, inline code evaluations, and Jupyter notebooks is different from executed files. See the documentation on soft scoping for more background. A good heuristic which will avoid these issues is to (1) never use loops outside of a function when you write .jl
files; and (2) if you ever use the global
keyword, assume something is wrong and you should put something in a function.
You can execute a .jl
file in several ways.
Within a terminal, you can provide the path to the file. For example,
julia --threads auto --project hello.jl
See the REPL section for more details on the commandline options.
Alternatively, within VS Code itself you can use the <Ctrl-F5>
to run the new file.
10.2.4. Using the Debugger#
To debug your function, first click to the left of a line of code to create a breakpoint (seen as a red dot).
Next, use <Ctrl-Shift-D>
or select the run and debug tab on the left in Julia to see
Then choose the Run and Debug
option and it will execute plot_results()
at the bottom of the file, and then stop inside at the breakpoint.
Note
Some users may see other options like Run active Julia file
instead of Run and Debug
in the run and debug tab.
You can use the toolbar at the top to step through the code, as described in the documentation.
As an alternative way to start the debugger, you can instead debug a call within the REPL with commands like @run plot_results()
.
Note
The Julia Debugger runs some of the code in an interpreted mode that might be far slower than typical compiled and optimized code. For this reason, it may not be possible to use it in all the same ways you might use something like the Matlab debugger. However, if you organize your code appropriately, you may find that the compile mode enables you to concentrate on debugging only some of the functions, while letting slow functions remain compiled.
10.3. The REPL#
Even if you are working primarily in .jl
and/or Jupyter Notebooks in Julia, you will need to become comfortable with the REPL. We saw some initial use of this when adding packages and exploring the code above, but the REPL has many more features.
10.3.1. Starting a REPL#
There are several ways to start the REPL.
Within VS Code, executing code inline will start it as required.
In the command palette of VS Code, choose
> Julia: Start REPL
Outside of VS Code, if julia was installed on your system path, you can simply type
julia
or with other options
The command line options for starting Julia are set to decent defaults for terminals running within VS Code, but you will want to set them yourself if starting the REPL otherwise.
As an example, the argument --threads
determines the number of threads that Julia starts with. If starting julia
on the command line without specifying any arguments, it will default to 1 (or check an environment variable). To have Julia automatically choose the number of threads based on the number of processors for your machine, pass the --threads auto
argument.
Note
VS Code sets the number of threads automatically based on the number of cores on your machine, but the value can be modified in its > Preferences: Open User Settings
and then search for Julia: Num Threads
.
The most important choice is the --project
toggle which determines whether you want to activate an existing project (or create a new one) when starting the interpreter. Since a key feature of Julia is to have fully reproducible environments, you will want to do this whenever possible.
To emphasize this point, this is an example of the ]st
showing the global environment has only the bare minimum of packages installed. With this workflow, all other packages are installed only when a given project is activated.
(@v1.8) pkg> st
Status `C:\Users\jesse\.julia\environments\v1.8\Project.toml`
[7073ff75] IJulia v1.23.2
[14b8a8f1] PkgTemplates v0.7.18
[295af30f] Revise v3.1.19
Note
A key difference between Julia and some other package managers is that it is capable of having different versions of each package for different projects - which ensures all projects are fully reproducible by you, your future self, and any other collaborators. While there is a global set of packages available (e.g. IJulia.jl
to ensure Jupyter support) you should try to keep the packages in different projects separated. See the documentation on environments and the package manager for more.
If you start the terminal without activating a project, you can activate it afterwards with ] activate .
or using Pkg; Pkg.activate()
.
To see this in action, within an external terminal we will open it using both methods, and then use ] st
to see which project is activated and which packages are available.
First, with julia --threads auto
we see that the globally installed packages are available at first, but that the existing Project.toml
and Manifest.toml
in that folder are chosen after we choose ] activate .
Next, with julia --threads auto --project
the project is automatically activated
Finally, if you choose the --project
option in a folder which doesn’t have an existing project file, it will create them as required.
A few other features of the REPL include,
10.3.2. More Features and Modes#
Hitting ;
brings you into shell mode, which lets you run bash commands (PowerShell on Windows)
; pwd
In addition, ?
will bring you into help mode.
The key use case is to find docstrings for functions and macros, e.g.
? print
10.4. Package Environments#
As discussed, the Julia package manager allowed you to create fully reproducible environments (in the same spirit as Python’s and Conda virtual environments).
As we saw before, ]
brings you into package mode. Some of the key choices are
] instantiate
(orusing Pkg; Pkg.instantiate()
in the normal julia mode) will check if you have all of the packages and versions mentioned in theProject.toml
andManifest.toml
files, and install as required.This feature will let you reproduce the entire environment and, if a
Manifest.toml
is available, the exact package versions used for a project. For example, these lecture notes use Project.toml and Manifest.toml - which you likely instantiated during installation after downloading these notebooks.
] add Expectations
will add a package (here,Expectations.jl
) to the activated project file (or the global environment if none is activated).Likewise,
] rm Expectations
will remove that package.] st
will show you a snapshot of what you have installed.] up
will upgrade versions of your packages to the latest versions possible given the graph of compatibility used in each.
Note
On some operating systems (such as OSX) REPL pasting may not work for package mode, and you will need to access it in the standard way (i.e., hit ]
first and then run your commands).
10.5. More Options and Configuration Choices#
VS Code and the related ecosystem have an enormous number of features and additional options.
The following are some optional choices, not all directly connected to Julia.
10.5.1. Optional Extensions#
While not required for these lectures, consider installing the following extensions. As before, you can search for them on the Marketplace or choose Install
from the webpages themselves.
Jupyter: VS Code increasingly supports Jupyter notebooks directly, and this extension provides the ability to open and edit
.ipynb
notebook files without installing Conda and runningjupyter lab
.GitLens: An extension that provides an enormous amount of detail on exact code changes within github repositories (e.g., seamless information on the time and individual who last modified each line of code)
GitHub Pull Requests and Issues: while VS Code supports the git version control natively, these extension provides additional features for working with repositories on GitHub itself.
Markdown All in One: For editing the markdown format, such as
README.md
and similar files.
10.5.2. VS Code as a LaTeX Editor#
VS Code has an outstanding LaTeX editing extension, which provides a good way to become comfortable with the tool and managing source code online.
Install a recent copy of tex
With a new VS Code session, install the following extensions
(Optional) Code Spell Checker
(Optional) If you wish to have the editor automatically compile and display the document when you save your
.tex
file: Then open the VS Code settings, and search forautobuild
to set the optionLatex-workshop > Latex > Auto Build: Run
toonSave
.
No further configuration should be required, but see the manual if you have problems.
While there many ways to execute a compilation workflow, one method is to use “magic comments” at the top of a latex file. This is not specific to LaTeX Workshop, and can be used by other tools.
In VS Code, create a new file, such as
rough_notes.tex
and copy in the following% !TEX program = pdflatex % !TEX enableSynctex = true \documentclass{article} \title{Rough Notes} \begin{document} \maketitle Some rough notes \end{document}
Save the document. If you enabled the automatic build option in your settings, this should compile it. Otherwise, use
F5
or the command palette> Latex Workshop: Build Latex Project
.If you hover over the magnifying glass icon near the top right hand corner, It should look something like,
Click on that link, or use
<Ctrl+Alt+V>
to get display the PDF Preview.The first time you do this, it will ask you to choose the PDF display. Choose
VSCode tab
If you modify the document and save (or manually rebuild) the view will update
If you double-click on the PDF it can take you to the synced section of the latex. Conversely, if you use the
<Ctrl+Alt+J>
or the palette> TeX Workshop: SyncTex from Cursor
it will find the appropriate section of the PDF based on your current cursor position in the.tex
file.
Select the Problems pane at the bottom of the screen (which likely shows 1 warning and no error) or open it with
<Ctrl+Shift+M>
In that screenshot, we have also selected the TeX
pane on the left hand side, which provides additional options for you to explore. All of them have command-palette equivalents.
If you wanted to have a bibliography, you would add it into the tex file as normal, and just add in the additional magic comment % !BIB program = bibtex
Finally, when using source code control, you will want to make sure you add the intermediate files to your .gitignore
(see here for more). Typically, you would want to ignore
*.aux
*.log
*.synctex.gz
*.pdf
Ignoring the *.pdf
is optional but strongly encouraged as it will ensure you don’t clog the repository with the binary pdf files, and make collaboration easier by preventing clashes on this file.
10.5.3. Font Choices#
Beyond their general use, the integrated terminals will use fonts installed within VS Code. Given that Julia code supports mathematical notation, the extra support in good fonts can be helpful.
JuliaMono and Cascadia Code and Fira Code are all good options.
You can adapt these or these instructions depending on the font choice.
If on Windows, for your external terminal consider installing Windows Terminal, which is built to support Cascadia and Powerline fonts.
10.5.4. Remote and Collaborative Extensions#
If you ever need to use clusters or work with reproducible containers, VS Code has strong support for those features. Key extensions for these are:
VS LiveShare: Collaborative coding within VS Code.
Remote Extensions Pack: Tools to access remote servers, local containers. Install OpenSSH if required.
SFTP: Secure copying of files to supported cloud services.
Windows users will find good support to access a local linux installation with the Windows Subsystem for Linux and the associated VS Code Extension.