# \[Seeking feedback\] Package for easy customization of startup.jl

**URL:** https://discourse.julialang.org/t/seeking-feedback-package-for-easy-customization-of-startup-jl/102351
**Category:** Tooling
**Tags:** package
**Created:** [August 1, 2023, 12:42pm UTC](https://discourse.julialang.org/t/seeking-feedback-package-for-easy-customization-of-startup-jl/102351 "2023-08-01T12:42:23Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)
#### Post date: [August 1, 2023, 12:42pm UTC](https://discourse.julialang.org/t/seeking-feedback-package-for-easy-customization-of-startup-jl/102351/1 "2023-08-01T12:42:23Z")

</div>

Hi all,

over in the other thread by @gdalle I suggested that his tutorials could include a small generator for `startup.jl` files with some common configurations like Revise.jl, OhMyREPL.jl, PkgTemplates.jl. He suggested that this could be useful for everyone not just newcomers so I quickly threw together this small package: [`StartupCustomizer.jl`](https://github.com/abraemer/StartupCustomizer.jl)

# Design ideas

- Easy to use: Ideally this should be a “batteries included” type of package.
- Extensibility: I only have 3 things in my startup.jl but other people might know of more handy things, so it should be easy to add new things.

# API

You can use `status()` to see what currently is in your startup.jl, `list()` to get a list of available modules, `describe(module)` to get detailed information on a module, `add(module...)`/`remove(module...)` to add/remove modules and `edit()` to edit the startup.jl directly by hand. Notably `add`ing modules also installs required packages into the global default environment.

I have implemented examples for `Revise.jl`, `OhMyREPL.jl` and `PkgTemplates.jl` because I am personally using these three.

# How things work

The main concept of this package is that of a `StartupModule` which handles something you want to put into your startup.jl. All one needs to do to add something new is to make a subtype of `AbstractStartupModule` and implement 4 methods `short_description`, `long_description`, `_dependencies` and `_generate`.

For `add`,`remove`,`status`, this package scans `startup.jl` to determine what it has written there previously. Only parts that are recognized are ever altered. This package marks section by wrapping them in comments like `# begin StartupCustomizer.Revise()` and `# end StartupCustomizer.Revise()`. These comments also serve as storage for the parameters of the modules, so modules should take care that they are reconstructable from their string representation.

Now I’d like to hear some feedback from you all:

1. The name: At first I thought to call it just `Startup.jl` because that is what this package is concerned with and if it grows into the default way of managing startup files maybe it’s not such a bad name after all. It could be confusing (when does someone talk about the package, when about the file?) and I think it is not my place to give it such a general name.
2. Do you have suggestions how to achieve its goal better/make it more robust? Right now I am writing comment lines into startup.jl to mark out the blocks. I also put the configuration of the modules there in stringform. This is clunky (because everything is written to string and needs to be reconstructed from a string) and for modules with more configuration (_cough_ `PkgTemplates.jl` _cough_) becomes somewhat messy but everything is self contained.
3. I only have Linux and don’t know how to best locate the default `startup.jl` on other platforms.
4. Speaking of testing… I am unsure how to write meaningful tests for this. Checking the generated file is easy of course but not a good test and I am not sure how to test the behavior of the generated file.
5. It would generally be better if the modules could generate Julia code and put that nicely formatted into startup.jl than to generate strings. Any suggestions for a pretty printing library for Julia code?
6. General style: I chose not to export the somewhat generic names of this package so they don’t clash with e.g. `InteractiveUtils.edit`. However that leads to rather verbose calls when using it.
7. Right now we only install required packages into the global environment but never remove them because the user might want them there for something else. Can you think of a better way of handling this?

Any feedback is welcome 🙂 I am too set on anything here, I made this rather quickly after getting the impulse from @gdalle

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [August 1, 2023, 1:51pm UTC](https://discourse.julialang.org/t/seeking-feedback-package-for-easy-customization-of-startup-jl/102351/2 "2023-08-01T13:51:12Z")

</div>

Sounds like an interesting idea. I don’t really play around with the startup file, but maybe I should start.

Regarding name: StartupTemplates.jl?

---

<div class="post-metadata">

### Author: ![fatteneder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fatteneder/32/33991_2.png) [@fatteneder](https://discourse.julialang.org/u/fatteneder)
#### Post date: [August 1, 2023, 2:12pm UTC](https://discourse.julialang.org/t/seeking-feedback-package-for-easy-customization-of-startup-jl/102351/3 "2023-08-01T14:12:51Z")

</div>

> [@abraemer](#):
>
> I only have Linux and don’t know how to best locate the default `startup.jl` on other platforms.

You could try searching paths listed in `DEPOT_PATH` for any `startup.jl` files.

---

<div class="post-metadata">

### Author: ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)
#### Post date: [August 1, 2023, 4:58pm UTC](https://discourse.julialang.org/t/seeking-feedback-package-for-easy-customization-of-startup-jl/102351/4 "2023-08-01T16:58:48Z")

</div>

Very cool tool, thanks @abraemer. This will go in the blog right away.

> [@abraemer](#):
>
> You can use `status()` to see what currently is in your startup.jl, `list()` to get a list of available modules, `describe(module)` to get detailed information on a module, `add(module...)`/`remove(module...)` to add/remove modules and `edit()` to edit the startup.jl directly by hand. Notably `add`ing modules also installs required packages into the global default environment.

This sounds very reasonable and minimalistic, love it.

> [@abraemer](#):
>
> The name

is just fine.

> [@abraemer](#):
>
> Do you have suggestions how to achieve its goal better/make it more robust?

Perhaps store different `.jl` files corresponding to the different `StartupModule`s, and concatenate them to the actual `startup.jl`?  
That would allow you to get nice Julia syntax highlighting, formatting, executability, etc. in your elementary bricks.

---

<div class="post-metadata">

### Author: ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)
#### Post date: [August 1, 2023, 6:49pm UTC](https://discourse.julialang.org/t/seeking-feedback-package-for-easy-customization-of-startup-jl/102351/5 "2023-08-01T18:49:12Z")

</div>

> [@fatteneder](#):
>
> You could try searching paths listed in `DEPOT_PATH` for any `startup.jl` files.

Thanks for the pointer. I’ll look into that.

> [@gdalle](#):
>
> Perhaps store different `.jl` files corresponding to the different `StartupModule`s, and concatenate them to the actual `startup.jl`?

That sounds like a nice idea. I’ll see how I can make that work.

---

<div class="post-metadata">

### Author: ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)
#### Post date: [August 2, 2023, 1:27pm UTC](https://discourse.julialang.org/t/seeking-feedback-package-for-easy-customization-of-startup-jl/102351/6 "2023-08-02T13:27:02Z")

</div>

So I changed the structure of the project to instead load code from template files, which I am rather happy with. I also added the [numbered prompt mode](https://docs.julialang.org/en/v1/stdlib/REPL/#Numbered-prompt) from the manual.

This package is good to go from my side and I would register it 🙂

---

<div class="post-metadata">

### Author: ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)
#### Post date: [August 2, 2023, 9:43pm UTC](https://discourse.julialang.org/t/seeking-feedback-package-for-easy-customization-of-startup-jl/102351/7 "2023-08-02T21:43:46Z")

</div>

@jacobusmmsmit time to bust out your exotic startup material?

---

<div class="post-metadata">

### Author: ![jacobusmmsmit](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jacobusmmsmit/32/217669_2.png) [@jacobusmmsmit](https://discourse.julialang.org/u/jacobusmmsmit)
#### Post date: [August 3, 2023, 9:31am UTC](https://discourse.julialang.org/t/seeking-feedback-package-for-easy-customization-of-startup-jl/102351/8 "2023-08-03T09:31:04Z")

</div>

It’s @fredrikekre’s originally, [his startup.jl](https://github.com/fredrikekre/.dotfiles/blob/master/.julia/config/startup.jl) contains some complex cool stuff.

I wonder if anyone else has done interesting things with AST transformations yet…

---

<div class="post-metadata">

### Author: ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)
#### Post date: [August 3, 2023, 10:13am UTC](https://discourse.julialang.org/t/seeking-feedback-package-for-easy-customization-of-startup-jl/102351/9 "2023-08-03T10:13:13Z")

</div>

Wow! That is cursed/impressive 😆

So the first part just makes it so, that typing :q (:r) quits/restarts Julia (dunno why the former is needed as Control+D achieves the same). The second part autoloads packages when certain macros are encountered. While certainly cool it probably is less impactful for Julia \>= 1.9 due to faster loading in general. So one could just always load these packages and startup shouldn’t get to slow.

Maybe autoloading packages is something that many users do in their `startup.jl` so it might be useful to support that.
