User reference
There are really only six functions that most users would be expected to call manually: revise
, includet
, Revise.track
, entr
, Revise.retry
, and Revise.errors
. Other user-level constructs might apply if you want to debug Revise or prevent it from watching specific packages, or for fine-grained handling of callbacks.
Revise.revise
— Functionrevise(; throw=false)
eval
any changes in the revision queue. See Revise.revision_queue
. If throw
is true
, throw any errors that occur during revision or callback; otherwise these are only logged.
revise(mod::Module; force::Bool=true)
Revise all files that define mod
.
If force=true
, reevaluate every definition in mod
, whether it was changed or not. This is useful to propagate an updated macro definition, or to force recompiling generated functions. Be warned, however, that this invalidates all the compiled code in your session that depends on mod
, and can lead to long recompilation times.
Revise.track
— FunctionRevise.track(Base)
Revise.track(Core.Compiler)
Revise.track(stdlib)
Track updates to the code in Julia's base
directory, base/compiler
, or one of its standard libraries.
Revise.track(mod::Module, file::AbstractString)
Revise.track(file::AbstractString)
Watch file
for updates and revise
loaded code with any changes. mod
is the module into which file
is evaluated; if omitted, it defaults to Main
.
If this produces many errors, check that you specified mod
correctly.
Revise.includet
— Functionincludet(filename)
Load filename
and track future changes. includet
is intended for quick "user scripts"; larger or more established projects are encouraged to put the code in one or more packages loaded with using
or import
instead of using includet
. See https://timholy.github.io/Revise.jl/stable/cookbook/ for tips about setting up the package workflow.
By default, includet
only tracks modifications to methods, not data. See the extended help for details. Note that this differs from packages, which evaluate all changes by default. This default behavior can be overridden; see Configuring the revise mode.
Extended help
Behavior and justification for the default revision mode (:evalmeth
)
includet
uses a default __revise_mode__ = :evalmeth
. The consequence is that if you change
a = [1]
f() = 1
to
a = [2]
f() = 2
then Revise will update f
but not a
.
This is the default choice for includet
because such files typically mix method definitions and data-handling. Data often has many untracked dependencies; later in the same file you might push!(a, 22)
, but Revise cannot determine whether you wish it to re-run that line after redefining a
. Consequently, the safest default choice is to leave the user in charge of data.
Workflow tips
If you have a series of computations that you want to run when you redefine your methods, consider separating your method definitions from your computations:
- method definitions go in a package, or a file that you
includet
once - the computations go in a separate file, that you re-
include
(no "t" at the end) each time you want to rerun your computations.
This can be automated using entr
.
Internals
includet
is essentially shorthand for
Revise.track(Main, filename; mode=:includet, skip_include=true)
Do not use includet
for packages, as those should be handled by using
or import
. If using
and import
aren't working, you may have packages in a non-standard location; try fixing it with something like push!(LOAD_PATH, "/path/to/my/private/repos")
. (If you're working with code in Base or one of Julia's standard libraries, use Revise.track(mod)
instead, where mod
is the module.)
includet
is deliberately non-recursive, so if filename
loads any other files, they will not be automatically tracked. (Call Revise.track
manually on each file, if you've already included
d all the code you need.)
Revise.entr
— Functionentr(f, files; all=false, postpone=false, pause=0.02)
entr(f, files, modules; all=false, postpone=false, pause=0.02)
Execute f()
whenever files or directories listed in files
, or code in modules
, updates. If all
is true
, also execute f()
as soon as code updates are detected in any module tracked by Revise.
entr
will process updates (and block your command line) until you press Ctrl-C. Unless postpone
is true
, f()
will be executed also when calling entr
, regardless of file changes. The pause
is the period (in seconds) that entr
will wait between being triggered and actually calling f()
, to handle clusters of modifications, such as those produced by saving files in certain text editors.
Example
entr(["/tmp/watched.txt"], [Pkg1, Pkg2]) do
println("update")
end
This will print "update" every time "/tmp/watched.txt"
or any of the code defining Pkg1
or Pkg2
gets updated.
Revise.retry
— FunctionRevise.retry()
Attempt to perform previously-failed revisions. This can be useful in cases of order-dependent errors.
Revise.errors
— FunctionRevise.errors()
Report the errors represented in Revise.queue_errors
. Errors are automatically reported the first time they are encountered, but this function can be used to report errors again.
Revise logs (debugging Revise)
Revise.debug_logger
— Functionlogger = Revise.debug_logger(; min_level=Debug)
Turn on debug logging (if min_level
is set to Debug
or better) and return the logger object. logger.logs
contains a list of the logged events. The items in this list are of type Revise.LogRecord
, with the following relevant fields:
group
: the event category. Revise currently uses the following groups:- "Action": a change was implemented, of type described in the
message
field. - "Parsing": a "significant" event in parsing. For these, examine the
message
field for more information. - "Watching": an indication that Revise determined that a particular file needed to be examined for possible code changes. This is typically done on the basis of
mtime
, the modification time of the file, and does not necessarily indicate that there were any changes.
- "Action": a change was implemented, of type described in the
message
: a string containing more information. Some examples:- For entries in the "Action" group,
message
can be"Eval"
when modifying old methods or defining new ones, "DeleteMethod" when deleting a method, and "LineOffset" to indicate that the line offset for a method was updated (the last only affects the printing of stacktraces upon error, it does not change how code runs) - Items with group "Parsing" and message "Diff" contain sets
:newexprs
and:oldexprs
that contain the expression unique to post- or pre-revision, respectively.
- For entries in the "Action" group,
kwargs
: a pairs list of any other data. This is usually specific to particulargroup
/message
combinations.
See also Revise.actions
and Revise.diffs
.
Revise.actions
— Functionactions(logger; line=false)
Return a vector of all log events in the "Action" group. "LineOffset" events are returned only if line=true
; by default the returned items are the events that modified methods in your session.
Revise.diffs
— Functiondiffs(logger)
Return a vector of all log events that encode a (non-empty) diff between two versions of a file.
Prevent Revise from watching specific packages
Revise.dont_watch_pkgs
— ConstantRevise.dont_watch_pkgs
Global variable, use push!(Revise.dont_watch_pkgs, :MyPackage)
to prevent Revise from tracking changes to MyPackage
. You can do this from the REPL or from your .julia/config/startup.jl
file.
See also Revise.silence
.
Revise.silence
— FunctionRevise.silence(pkg)
Silence warnings about not tracking changes to package pkg
.
Revise module
Revise
— ModuleRevise.jl tracks source code changes and incorporates the changes to a running Julia session.
Revise.jl works behind-the-scenes. To track a package, e.g. Example
:
(@v1.6) pkg> dev Example # make a development copy of the package
[...pkg output omitted...]
julia> using Revise # this must come before the package under development
julia> using Example
[...develop the package...] # Revise.jl will automatically update package functionality to match code changes
Functions in Revise.jl that may come handy in special circumstances:
Revise.track
: track updates toBase
Julia itself orCore.Compiler
includet
: load a file and track future changes. Intended for small, quick worksentr
: call an additional function whenever code updatesrevise
: evaluate any changes inRevise.revision_queue
or every definition in a moduleRevise.retry
: perform previously-failed revisions. Useful in cases of order-dependent errorsRevise.errors
: report the errors represented inRevise.queue_errors