# \[ANN\] Higher productivity (fewer Julia restarts) with Revise.jl

**URL:** <https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564>\
**Category:** Community\
**Tags:** package, announcement, productivity, development\
**Created:** [June 30, 2017, 1:36pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564 "2017-06-30T13:36:56Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [June 30, 2017, 1:36pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/1 "2017-06-30T13:36:56Z")

</div>

I’m announcing a new package that may speed up your development: [https://github.com/timholy/Revise.jl](https://github.com/timholy/Revise.jl). Revise makes it easier to update code and have the changes take effect immediately, without having to restart Julia. Please see the README for more information.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 5, 2017, 6:12am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/2 "2017-07-05T06:12:59Z")

</div>

This package revolutionized my workflow in a few days. Thanks!

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [July 5, 2017, 7:53am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/3 "2017-07-05T07:53:12Z")

</div>

Glad to hear it! I find that old habits die hard—I still sometimes restart Julia unnecessarily—but it’s been very good for my workflow too.

Thanks to good feedback from users, `v0.0.3` has been released with better support for vim, IJulia, and a broader collection of Julia packages. If it doesn’t work for your use-cases, please continue to report issues.

---

<div class="post-metadata">

**Author:** ![TsurHerman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tsurherman/32/1234_2.png) [@TsurHerman](https://discourse.julialang.org/u/TsurHerman)\
**Post date:** [July 5, 2017, 12:31pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/4 "2017-07-05T12:31:09Z")

</div>

Suggestion for even smoother workflow if you are working with Juno:  
Besides working with Revise or CloberringReload(if you are on 0.5), set Juno to cycler mode  
this way it makes a Julia instance ready in the background.

Moreover add a .junorc.jl in your home folder and have it import any commonly used packages.  
This saves additional few seconds of start-up time

I also added an asynchronous task with many yields , that does a “workout” for commonly used functions  
that are slow the first time… many yields because I want it to be responsive even if it didn’t finish its workout.

This way when I do restart Julia , it starts in a nice warm and nimble state.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [July 10, 2017, 8:51am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/5 "2017-07-10T08:51:26Z")

</div>

> [@tim.holy](#):
>
> I find that old habits die hard—I still sometimes restart Julia unnecessarily

To break my habit I wanted ctrl-d to ask `Exit? [Y/n]` before exiting. I came up with this `.juliarc.jl` bit but it hangs at the `readline`. Anyone know how to do this?

```julia
    ctrl_d_ask = Dict{Any,Any}(
        "^D" =>
        function (s,o...)
            if Base.LineEdit.buffer(s).size > 0
                Base.LineEdit.edit_delete(s)
            else
                println("Exit? [Y/n]")
                answer = readline(STDIN)
                if answer=="" || lowercase(answer)=="y"
                    println(Base.LineEdit.terminal(s))
                    return :abort
                else
                    return nothing
                end
            end
        end
        )
    function customize_keys(repl)
        repl.interface = Base.REPL.setup_interface(repl; extra_repl_keymap = ctrl_d_ask)
    end
    atreplinit(customize_keys)

```

---

<div class="post-metadata">

**Author:** ![Evey](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evey/32/214967_2.png) [@Evey](https://discourse.julialang.org/u/Evey)\
**Post date:** [July 11, 2017, 7:07am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/6 "2017-07-11T07:07:04Z")

</div>

I really like the idea of this package, ~~even though it currently only works for the first few file changes. I’m not really sure what is going on, need to test it some more.~~  
EDIT: It seems to be working now. Yay.

Anyway, I’m kind of curious why you have to do:

```julia
@schedule begin
    sleep(0.1)
    @eval using Revise
end

```

in `.juliarc.jl`?

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [July 11, 2017, 9:44am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/7 "2017-07-11T09:44:00Z")

</div>

Do you mean, “as opposed to simply `using Revise` in `.juliarc.jl`”? The `@schedule` is needed because `.juliarc.jl` gets executed before the REPL code is fully initialized. Revise’s ` __init__ ` function alters an important component of the REPL code (shutting down one “service” and starting a modified one), so you have to do something to wait until the REPL code is initialized.

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [July 11, 2017, 11:53am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/8 "2017-07-11T11:53:23Z")

</div>

Thanks for this trick!! I have a function to change the prompt (to include the current branh-name, to no be lost when I have a handful of open prompts to compare e.g. performances for a PR), but never could find a way to call this function from my “.juliarrc.jl”. This is really neat, you solve one of my longstanding problems (although I believe there should eventually be a cleaner to achieve the same).

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [July 11, 2017, 12:07pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/9 "2017-07-11T12:07:01Z")

</div>

If you know for certain that you’re using the REPL, something like `wait(Task(() -> while !isdefined(Base, :active_repl_backend) end))` might be even better than `sleep(0.1)`. In Requires I want to make sure I support Juno/IJulia too, so there may never be a REPL. So I chose the more braindead solution.

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [July 11, 2017, 6:07pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/10 "2017-07-11T18:07:41Z")

</div>

> [@tim.holy](#):
>
> wait(Task(() -\> while !isdefined(Base, :active\_repl\_backend) end))

Looks neat, but after playing a bit with it, I can’t make it work (I will need to read more about tasks to understand); it’s looks like the task is never run.

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [July 11, 2017, 9:36pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/11 "2017-07-11T21:36:41Z")

</div>

Even with `@schedule` I have to manually call `revise()`.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [July 13, 2017, 3:27pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/12 "2017-07-13T15:27:07Z")

</div>

That’s unexpected. Is there an error message? What happens if you increase the sleep time? Are you loading any other packages in your `.juliarc.jl`? If so, they won’t get tracked unless you make sure you load Revise first.

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [July 13, 2017, 6:38pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/13 "2017-07-13T18:38:03Z")

</div>

No error message. Here’s my current rc:

```julia
@schedule begin
    sleep(0.1)
    @eval using Revise
end

atreplinit((_)->begin
  Base.require(:TerminalExtensions)
  Base.require(:MiscGraphUtils)
end)

```

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [July 13, 2017, 6:44pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/14 "2017-07-13T18:44:58Z")

</div>

Maybe `TeminalExtensions` does its own messing with things, perhaps try commenting that one out.

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [July 13, 2017, 6:51pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/15 "2017-07-13T18:51:59Z")

</div>

It wasn’t `TerminalExtensions`, it was `MiscGraphUtils` which depended on `LightGraphs` (which was what I was revising). This seems to indicate that `atreplinit` happens BEFORE `@schedule`, right?

Also: if you remove a function from the source, it persists even after a revise() (this is not terribly surprising, I guess):

```julia
julia> LightGraphs.foo(g)
33

# remove foo from source, save.
julia> revise()

julia> LightGraphs.foo(g)
33

```

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [July 13, 2017, 6:55pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/16 "2017-07-13T18:55:48Z")

</div>

> This seems to indicate that atreplinit happens BEFORE @schedule, right?

Well, technically the `@schedule` happens immediately, but then execution progresses. Meanwhile the Task’s first action is to sleep 0.1s; if that takes longer than REPL initialization, then Revise gets loaded after those other packages. If you never use IJulia/Juno, you could just add `Revise` to the `atreplinit` list.

> if you remove a function from the source, it persists even after a revise

Yes, this is documented in the README.

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [July 13, 2017, 7:01pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/17 "2017-07-13T19:01:00Z")

</div>

> If you never use IJulia/Juno, you could just add Revise to the atreplinit list.

I don’t, but it doesn’t work as I might expect:

```julia
atreplinit((_)->begin
  @eval using Revise
  Base.require(:TerminalExtensions)
  Base.require(:MiscGraphUtils)
end)

```

requires me to use `revise()` for LightGraphs (after a `using LightGraphs` typed into the REPL), and

```julia
atreplinit((_)->begin
  Base.require(:Revise)
  Base.require(:TerminalExtensions)
  Base.require(:MiscGraphUtils)
end)

```

doesn’t load Revise at all.

---

<div class="post-metadata">

**Author:** ![anon43133060](https://avatars.discourse-cdn.com/v4/letter/a/57b2e6/32.png) [@anon43133060](https://discourse.julialang.org/u/anon43133060)\
**Post date:** [July 22, 2017, 12:57pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/18 "2017-07-22T12:57:08Z")

</div>

This is a lifesaver! How hard would it be to make it a part of standard Julia REPL?

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [July 22, 2017, 1:03pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/19 "2017-07-22T13:03:23Z")

</div>

I personally think it’s worth considering, but the scary thing would be that if it doesn’t work for everyone then it could handicap the REPL (which would be pretty catastrophic). If we want to make progress towards such a future, the most important thing is for anyone who experiences trouble with the package to please report bugs!

(Along these lines, OSX users please upgrade to the 0.0.4 release once [the METADATA tag](https://github.com/JuliaLang/METADATA.jl/pull/10381) gets merged.)

---

<div class="post-metadata">

**Author:** ![Nitin\_Arora](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nitin_arora/32/1174_2.png) [@Nitin\_Arora](https://discourse.julialang.org/u/Nitin_Arora)\
**Post date:** [July 22, 2017, 8:21pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/20 "2017-07-22T20:21:58Z")

</div>

Just found out about this… This will change my life ! Thank you @tim.holy for doing this.

[Next page](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564.md?page=2)
