microsoft / terminal

The new Windows Terminal and the original Windows console host, all in the same place!
MIT License
94.74k stars 8.2k forks source link

Add support for roaming settings.json or storing it elsewhere #2933

Open patriksvensson opened 4 years ago

patriksvensson commented 4 years ago

Note: 📌 Pinned comment: https://github.com/microsoft/terminal/issues/2933#issuecomment-536652883


Description of the new feature/enhancement

I have three different computers that I use for work. I keep my PowerShell profile in a GitHub repository and dot source it in my local PowerShell profile. That way I will only need to do a git pull on my profile repository to get all changes propagated on each computer.

It would be great if I could do something similar with my Windows Terminal settings by simply stating in my local settings.json file that the "real" settings could be found somewhere else.

(It could even be that the loaded profile acts like a base for the settings on the computer so things could be overridden, but that is a completely different issue that remains to be opened)

I'm aware that I might have overlooked something here, but would love to start a discussion about this since I suspect that I'm not the only one with this "problem".

Proposed technical implementation details (optional)

{
    "$schema": "https://aka.ms/terminal-profiles-schema",
    "globals": {
        "loadProfileFrom": "C:/Source/git/profiles/terminal_profile.json"
    }
brandonh-msft commented 4 years ago

any reason we can't just use the UWP Roaming data store? https://docs.microsoft.com/en-us/windows/uwp/design/app-settings/store-and-retrieve-app-data#roaming-data

I know this isn't a true UWP app, but Centennials can still use the UWP APIs, right?

DHowett-MSFT commented 4 years ago

We actually used to roam your settings using those exact APIs, but it caused us way more headache than it was worth. There’s a couple things we need to nail before we consider turning roaming back on.

brandonh-msft commented 4 years ago

yeah was just coming back to edit.

looks like per here: https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/desktop-to-uwp-enhance and here: https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/desktop-to-uwp-supported-api

we can't simply use RoamingFolder as I'd hoped? In lieu of this, then, @patriksvensson's approach is probably the best we'll get and users - well I, for one - could simply point at a OneDrive (or similar) location.

zadjii-msft commented 4 years ago

I'm more using this issue as a tracker for "add a way to import settings from other paths" than a "re-enable settings roaming". Using RoamingState for storing the settings was a pain. However, I think that we all agree adding support for importing settings from another location is a good idea, but one that needs careful thought and preferably a spec to go with it.

This is even a scenario referenced in the original cascading settings spec, as something we could consider in the future.

1770 was the original bug tracking disabling roaming settings. Note the pile of other issues that were dupe'd to it.


April 15, 2022 edit:

I'm sneaking in here to add some notes about what re-enabling this again might look like. I'm reusing this old comment to avoid pinging folks till I have a plan.

What went wrong the first time

Plan for this time

Other things to keep in mind

patriksvensson commented 4 years ago

@zadjii-msft What's the process for creating a spec for something? Do you have an RFC-process or similar?

zadjii-msft commented 4 years ago

@patriksvensson We don't have an official "RFC" process, but we do have a semi-formal spec review process. This helps us ensure the entire team is on-board with more complicated features, and for scenarios like this one, some of the more complicated edge cases have been thought out. I'd refer to the following:

patriksvensson commented 4 years ago

@zadjii-msft Would it help if I (or someone else) drafted up a spec to get the ball rolling?

zadjii-msft commented 4 years ago

I think that would be very helpful :)

jpetkau commented 4 years ago

As a workaround for this, it's possible to make profiles.json a symlink to a shared settings file in Roaming or OneDrive or Dropbox or whatever.

This mostly works, except terminal doesn't notice changes to the actual file. It only watches the symlink. So hot-reloading of changes doesn't work.

Of course roaming just magically working would be better.

chwarr commented 4 years ago

There's a related issue in this space, #4566 "Consider adding a WT_PROFILE env var pointing to settings file for 1.0 release".

It proposes setting the environment variable WT_PROFILE to the path of the user's settings file. Copying a comment that I made on that here:

My expectation of a variable like WT_PROFILE would be that I could [also] use it to change where Windows Terminal reads user settings from. ...

Based on how other, similar software works, I think it would make sense if Windows Terminal only read this environment variable at process start up and then monitored the path for changes. It would also be reasonable for Windows Terminal to detect changes to the environment "template" by handling WM_SETTINGCHANGE notifications. (Though, there are some subtle details to consider about when changes are applied. Lots of thoughts in #1125, "Feature Request: Terminal should listen for the WM_SETTINGCHANGE for environment variable updates".)

patriksvensson commented 4 years ago

If anyone is interested in an interim solution to this, I've written some instructions here: https://www.patriksvensson.se/2019/12/roaming-profiles-with-windows-terminal

DavidGamba commented 4 years ago

If the file watcher that monitors profiles.json can detect a symlink and watch the target instead many users would easily backup their config in multiple ways and still get the full benefits of hot reload of the config.

DavidGamba commented 4 years ago

If the file watcher that monitors profiles.json can detect a symlink and watch the target instead many users would easily backup their config in multiple ways and still get the full benefits of hot reload of the config.

zadjii-msft commented 4 years ago

From @MartinSGill in #5638

Proposed technical implementation details (optional)

The common linux practice of using a settings.d style folder and loading all files in that folder seems like a good approach to me.

* Settings.json defines an "include" directory (environment variables permitted)

* Settings loads all files in that folder in alphabetical order.

* Settings adds/overrides settings based on loaded files.

* Additional files would all have the same structure/schema as the default settings.json

* [Extra Credit] Support multiple folders, allow shared/user settings.
MartinSGill commented 4 years ago

Advantages I see for my proposed implementation:

scottwillmoore commented 3 years ago

As a non-ideal workaround for any that want to sync settings.json into their dotfiles while preserving the ability to hot reload, you can a hard link instead of a symbolic link. The file will remain synchronised with your dotfiles and a hard link will still trigger the filesystem events required to trigger a hot reload provided that you edit settings.json from the original path (just press Ctrl+, in the terminal).

An alternative approach that I have read somewhere else (but cannot remember where...) is to create a junction or symlink for the LocalState folder (the folder that contains settings.json) and I believe this will detect and trigger a hot reload in all cases.

patricknelson commented 3 years ago

An alternative approach that I have read somewhere else (but cannot remember where...) is to create a junction or symlink for the LocalState folder (the folder that contains settings.json) and I believe this will detect and trigger a hot reload in all cases.

I use Link Shell Extension for this. Also, I just tried your recommendation (dropping LocalState folder as a symbolic link) and it worked for me! Initially it didn't work since I only symlinked the settings.json. Now I can save it in Google Drive, edit it from either location and it'll update live.

Firehawke commented 3 years ago

I'll second Link Shell Extension. It's a really useful tool for a lot of different purposes. I don't want to get too far off topic, but I'll just briefly add that I used junctions via LSE to have Steam stuff on a non-C drive before Steam supported multi-drive libraries. I still use a lot of junctions to keep large parts of my system config on private cloud storage.

bavis-m commented 3 years ago

It appears like a Junction point to LocalState allows settings.json to dynamically update, but not a symlink (either to LocalState or settings.json). Can anyone else confirm these behaviour? A couple of replies here seem to suggest a symlink will work (which I would like, since I can't put a junction to my config repo which I usually have checked out in WSL).

razamatan commented 3 years ago

so i'm here b/c i just switched to wsl2, and i have a setup where my dotfiles are for linux and replicated by git. therefore, my dotfiles live in wsl. under wsl1, since the wsl rootfs was readily accessible via windows, i had my %LOCALAPPDATA%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json linked to the file in wsl (dir output: <SYMLINK> settings.json [\\wsl$\Ubuntu\home\razamatan\.dotfiles\settings.json]).

since wsl2 switched to vhd's, if i try to open terminal w/o starting wsl to load the vhd, i get the "Encountered errors while loading user settings" error dialog. i have to remember to always start wsl to allow wt to be able to read from that symlink.

it would be great to load wsl if trying to access any symlink that points to wsl paths. don't know if this belongs to wsl (https://github.com/microsoft/WSL/issues/6524) or wt as an issue, but posting here just in case.

*edit: just tried making settings.json a junctioned symlink, but that never works, even w/ wsl loaded...

ghost commented 3 years ago

Add Cloud sync support with our Microsoft account.

thernstig commented 3 years ago

If anything, I think to be best-in-class it should follow how VS Code does this. FIrst let a user have User settings as well as Machine settings (which takes precedence over User settings when on a particular machine, but both should be synced still for backup purposes). Then add different Authentication providers that one can connect to, to sync the settings automatically. Examples of such providers: Github account, Microsoft account.

Syncing is then done seamlessly in the background when logged in. You can get history of syncs. Etc.

Falven commented 3 years ago

If anything, I think to be best-in-class it should follow how VS Code does this. FIrst let a user have User settings as well as Machine settings (which takes precedence over User settings when on a particular machine, but both should be synced still for backup purposes). Then add different Authentication providers that one can connect to, to sync the settings automatically. Examples of such providers: Github account, Microsoft account.

Syncing is then done seamlessly in the background when logged in. You can get history of syncs. Etc.

Any ideas if this is being implemented? I see the thread being closed and reopened multiple times but no work item linked or anything.

zadjii-msft commented 3 years ago

I see the thread being closed and reopened multiple times but no work item linked or anything.

???

This thread has remained open since it was first filed. Maybe you posted on the wrong thread?

We're not working on this currently, nor do we have plans to do this in the 2.0 timeframe. The original roaming settings were a pain, but easy to implement. The VsCode method of roaming though sounds like quite a bit more work. Better for sure, but not something we're about to get to any time soon.

Falven commented 3 years ago

We're not working on this currently, nor do we have plans to do this in the 2.0 timeframe. The original roaming settings were a pain, but easy to implement. The VsCode method of roaming though sounds like quite a bit more work. Better for sure, but not something we're about to get to any time soon.

Why not? It could be developed with community support. The source code to do this is already available in the VS Code repository, it is production-tested, and it includes tests... As an aside I would hope that at a minimum WT should have extensibility as a major milestone in the roadmap to allow people to develop plugins such as this.

zadjii-msft commented 3 years ago

I would LOVE to have community help implementing this!

Just because we don't have time on the schedule to design/implement a feature ourselves, doesn't mean we aren't willing to help the community with such a feature. I just don't want to commit to anything, if we haven't explicitly allocated engineers to finishing it ☺️.

\

awakecoding commented 2 years ago

I'm taking a chance here to suggest exactly what I intend to patch on my own builds to fit my needs: modify GetBaseSettingsPath to check for an environment variable "WT_BASE_SETTINGS_PATH" and use it if it's present instead of the default path. I really don't need anything more than that, as I would just launch Windows Terminal with different environment variables to make it point to different directories with injected settings.

image

Is there any chance that such a small change could be considered? I don't care about the environment variable name, just that we can use an environment variable (or command-line parameter) to override the base settings path.

DHowett commented 2 years ago

I took a crack at writing up the open questions about how a configurable base (be it a command line argument, environment variable, etc.) would work over at https://github.com/microsoft/terminal/issues/6687#issuecomment-650382579 :smile:

awakecoding commented 2 years ago

I took a crack at writing up the open questions about how a configurable base (be it a command line argument, environment variable, etc.) would work over at #6687 (comment) 😄

This looks good to me, is there a branch with a prototype for the suggested change? Also, while settings.json is the primary file used by Windows Terminal, would it better to override the directory containing settings.json rather than the full path to settings.json, such that if Windows Terminal decides to store more files in the future, we wouldn't need to modify it again to override additional paths? Overriding the base path containing all files appears to be the safest option long term.

patricknelson commented 2 years ago

Thanks for calling that out @DHowett

Hmm… since some of us want to synchronize profiles and others want the ability to parameterize via CLI which profile to use, have we considered separating this into two components? i.e.

  1. Directory to load profiles from
  2. The actual JSON file to load (must be a file, not a path and cannot be relative)

I say this since it might help to abstract away our concerns of allowing it to be roaming whilst also facilitating parametrized variability without being too tightly bound to the actual path. For example, both wt -c profile1.json and wt -c profile2.json would still work and are separate from where we decide to put them. This also suggests of course that, if the directory itself isn’t provided as a parameter as well (or some kind of env var, cringe I know) that you’ll have to devise a sane default. Presumably it’d still be in the current directory where this file is already stored and/or also configurable at some higher global level, wherever that may be.

I’m just trying to offer a concept that might help reconcile these two features amicably without it getting too complicated later on. 🤞

DanielLaberge commented 2 years ago

Please consider making this issue higher priority, or #6687, whichever is easier to implement.

I suspect a lot of users are suffering from this pain point: they work on multiple machines and currently have no means of loading profiles from one shared location like OneDrive or Dropbox, etc. Having to manually copy and paste profiles across all our machines, everything something is added or changed is frustrating and shouldn't be required in this day and age.

The amount of comments and duplicated issues in this and #6687 should be a good indication of the interest.

thernstig commented 2 years ago

Take inspiration from VS Code, the same way you took inspiration for the command pane from VS Code. They have authentication providers that can be used to sync settings. With logs, conflict resolution etc. etc. They spent a good chunk of UX on this already so I believe there is much to gain to just look at their solution UX-wise.

stevenvolckaert commented 2 years ago

What is the status on this feature request?

Is it possible somehow to roam the settings across several computers at the moment, and if so, what's the most recommended way to do it?

Is the symbolic link workaround mentioned here still the way to go?

Thank you very much for your insights!

hapylestat commented 2 years ago

@jpetkau the whole purpose of roaming settings.json, to make it auto-pickable on another systems and not bother with reconfiguring each system manually. I have like 3-4 systems and it is a headache to make same changes x4 times

hapylestat commented 2 years ago

@thernstig UX wise it's really easy, if you use MS enabled account and OneDrive, just use "Documents" folder or whatever to keep the settings, as those folders already are used in a way, that it auto-synced via OneDrive.

In my case, I'm keeping oh-my-posh in an OneDrive, and when I'm opening the terminal on another PC/VM - it automatically download everything and setting up it for me. (thanks for Powershell able to autoload user profiles)

4wk- commented 1 year ago

Hello. Sorry for "thread bumping" this issue but it's been some time since the last update, same in #6687.

Like a lot of users, I came here to see if there was a way to just store the settings.json file elsewhere, so it can be synced and backed-up by Dropbox/Onedrive/Drive (or even backup manually to a hard drive for instance).

The only workaround we might have is using a windows `hardlink as described here

zadjii-msft commented 1 year ago

Nope, no real updates to share at this time. I had half a thought about it that I edited into a comment above, just trying to enumerate the edge cases, but didn't get farther than that.

ghost commented 1 year ago

Hello. Sorry for "thread bumping" this issue but it's been some time since the last update, same in #6687.

Like a lot of users, I came here to see if there was a way to just store the settings.json file elsewhere, so it can be synced and backed-up by Dropbox/Onedrive/Drive (or even backup manually to a hard drive for instance).

The only workaround we might have is using a windows `hardlink as described here: https://superuser.com/questions/1667853/how-to-change-the-location-of-settings-json-file-in-windows-terminal

referring to the Superuser question, that's not where my Windows Terminal's settings file is located, it's here

C:\Users\UserName\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState

and I can easily use PowerShell to automate the process of copying my personalized settings file from my OneDrive to that location after every time I clean install Windows.

PowerShell is like the God of automation lol

4wk- commented 1 year ago

@lulMeow My json file is located like yours. I've commented SO for the sake of it. Actually, I've add another answer with more details. Yes, PowerShell can do a lot, but storing the file elsewhere would allow us to set it once and forgot about it, and still being always synced.

RollsChris commented 11 months ago

hey, bump, i cant really see why this is an issue to implement?

et304383 commented 11 months ago

In 2023 (nearly 2024), having to copy a settings file manually from one machine to the other should NOT be a thing.

Considering this and VSCode are the two core dev tools from Microsoft, this task should be higher priority. We should have settings sync in the cloud just like VSCode.

RollsChris commented 10 months ago

I really like how PowerShell do their profile, you can source another file in "Their profile file".

So I do this at the top of my profile:

  . "$env:GITHUB_REPOS_PATH\machine\powershell\Microsoft.PowerShell_profile.ps1";

Me casa su casa 😎

huenrong commented 5 months ago

Hi, Is it possible to add an option to each configuration file to choose whether to synchronize the configuration file?

carlos-zamora commented 1 month ago

Dupping a few issues to this one:

17277

https://github.com/microsoft/terminal/issues/17277#issue-2300424002

Description of the new feature/enhancement

I use many different machines on a daily basis, for example my work laptop, my development laptop, my testing laptop, my private laptop, my private Tower etc.

On each Device I need to import the full Config of Windows Terminal. A way to synchronise all the Terminal Config files would be insanely great and would really hype up this terminal soo much more!!!

PowerToys already has a Backup option, could similar thing be done for windows-terminal? I'd even consider github integration a nice idea, as this would allow for easy fetching from a raw.githubusercontent link. (I wouldn't mind the config being public).

Also something like fully remote fetching would be nice, for example the machine fetches the config from remote github repository and on no internet it fallbacks to a cached version.

Proposed technical implementation details (optional)

The Github Integration to the initial Backup + Restore would be like a nice-to-have addon to keep in mine, but could also be done through scripts.

17513

https://github.com/microsoft/terminal/issues/17513#issue-2389401309

Description of the new feature/enhancement

It would be ideal to back up Terminal settings to a different folder (for example, C:\Users\username\OneDrive\Documents\Terminal). Every time that we want to back up Terminal settings, we have to navigate to the folder like %LocalAppData%\packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState and copy and paste the settings.json file to another folder. Also, every time that we want to restore Terminal settings, we have to navigate the settings.json file to a folder and copy and paste it to %LocalAppData%\packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState.

Proposed technical implementation details (optional)

Add Backup and Restore buttons in the Terminal settings.

wolf99 commented 1 month ago

Small word of caution; if the synchronisation is via git repo, then there should also be some way to abstract secrets, such as usernames on paths, SSH creds, etc.

TomLewis commented 1 month ago

This should be a higher priority, why can this not sync with a windows account, its a widows product.

awakecoding commented 1 month ago

FYI - we went for a simple patch in our Windows Terminal distribution that accepts the WT_BASE_SETTINGS_PATH environment variable to override where WT stores its settings, and we've been using it for the past two years without issue. I haven't submitted a pull request for the simple reason that there doesn't seem to be consensus on how this should be fixed upstream, but for our needs, we needed a way to create isolated, injectable configurations to launch WT from Remote Desktop Manager, and an environment variable worked well.

mu88 commented 3 weeks ago

@carlos-zamora / @zadjii-msft is there any news about that?