talonhub / community

Voice command set for Talon, community-supported.
MIT License
622 stars 771 forks source link

Please provide a way to change settings without modifying the repository #1384

Open jaresty opened 7 months ago

jaresty commented 7 months ago

Currently, the talon settings file is committed to this repository. If I want to change those settings that are committed to the repository I need to deal with uncommitted changes or maintain my own branch. Some options that could work:

ekuiter commented 6 months ago

A fourth option (which I currently use) is to maintain your own .talon Git repository, put almost everything but the user directory into .gitignore, and add community as a Git submodule (along with other plugins like cursorless). Then, to override stuff from community:

This has the added benefit that you can control (using Git submodule commands) the versions of community and other plugins (e.g., to update to new versions without tedious merging or to roll back undesired changes). Also, setting up talon on another computer is now a simple git clone --recursive and creating the symbolic link as shown above.

jaresty commented 6 months ago

I've been told that the trick with talon files is that more specific matching always wins. You can override the settings file by adding a more specific tag. There is also an open pull request which changes many settings to talon list files that can be overridden https://github.com/talonhub/community/pull/1382

jaresty commented 6 months ago

I think there are various ways of solving this problem and this is evidence that this is a real issue for some.

jaresty commented 2 months ago

Adding some documentation to the README to explain how to use the talon list files to override things such as modifier keys (https://github.com/talonhub/community/pull/1477)

jaresty commented 2 months ago

I also added a pull request to the contributing guidelines to suggest a way to provide settings that will be a little more friendly to folks who are not forking the community repository: https://github.com/talonhub/community/pull/1482

bentitmus commented 1 month ago

Edit: ignore this I made a mistake

I tried the option @ekuiter gave, but that doesn't work for me on macOS because Python fails in core/user_settings.py as the symlink is not a directory so it tries to create settings which fails (and then everything breaks). A really simple fix for this in the short term is to use the following logic for finding settings:

# NOTE: Store settings in a `settings` directory at the same level as `community`
#   but fallback on the `community/settings` directory
SETTINGS_DIR = Path(__file__).parents[2] / "settings"
if not SETTINGS_DIR.is_dir():
    SETTINGS_DIR = Path(__file__).parents[1] / "settings"
if not SETTINGS_DIR.is_dir():
    os.mkdir(SETTINGS_DIR)

This should avoid breaking anyone's existing set-up but also allow these files to be commited in a repo. I can raise a PR for this, but won't bother if it will be rejected.

jaresty commented 1 month ago

You don't need to modify the repo - I have it working without modification based on my dotfiles on macos: https://github.com/jaresty/mac-dotfiles

bentitmus commented 1 month ago

Edit: ignore this I made a mistake

You're doing this with symlinks (created by the Makefile) which is what I had and it didn't work for me. Here's the error message I get in my Talon log:

2024-08-13 18:15:29.992 ERROR user.community.core.system_paths (/Users/ben/.talon/user/community/core/system_paths.py) import failed
   18:          lib/python3.11/threading.py:995 * # loader thread
   17:          lib/python3.11/threading.py:1038* 
   16:          lib/python3.11/threading.py:975 * 
   15:              app/resources/loader.py:853 | 
   14:              app/resources/loader.py:785 | 
   13:              app/resources/loader.py:645 | 
   12:              app/resources/loader.py:661 | 
   11:              app/resources/loader.py:716 | 
   10:              app/resources/loader.py:425 | # [stack splice]
    9: lib/python3.11/importlib/__init__.py:126 | 
    8:              app/resources/loader.py:240 | 
    7:              app/resources/loader.py:235 | 
    6:  user/community/core/system_paths.py:11  | from .user_settings import get_list_fr..
    5:              app/resources/loader.py:359 | 
    4:              app/resources/loader.py:240 | 
    3:              app/resources/loader.py:235 | 
    2: user/community/core/user_settings.py:12  | os.mkdir(SETTINGS_DIR)
    1:                                            ^^^^^^^^^^^^^^^^^^^^^^
FileExistsError: [Errno 17] File exists: '/Users/ben/.talon/user/community/settings'

It's failing on:

if not SETTINGS_DIR.is_dir():
    os.mkdir(SETTINGS_DIR)

because SETTINGS_DIR.is_dir() is false.

I created a symlink pointing from ~/.talon/user/community/settings to ~/.talon/user/local/settings.

Here's my GitHub .config directory, and at the end of my INSTALL.macos file I set-up the symlinks.

jaresty commented 1 month ago

I've been running with symlinks without issues for a while. This is the link I set up:


ln -sf ~/mac-dotfiles/talon-settings ../.talon/user/community/settings

Are you making the same symlink or doing something different?

jaresty commented 1 month ago

Can you try using ls on your symlink to verify you can follow the link?

bentitmus commented 1 month ago

Yes, user incompetence I'm afraid! I thought I had checked this but clearly not as I had it pointing to the wrong place.

AndyGlew commented 1 week ago

"the trick with talon files is that more specific matching always wins" is slightly suboptimal, when you don't want more specific matching, when you want to override something completely. AFAICT the way to do this in current Talon is to create a fake more specific context, e.g. a tag that you nearly always leave set[*], and then create .talons/etc. with that apparently more narrow scope. unfortunately AFAICT sometimes one has to go and add "not thatTagOrScopeOrMode" to the stuff that you are overriding, if you are not replacing something, but just plain disabling something.

In the UNIX community PATHs are the standard way to override something X, without modifying X: put X' earlier in the PATH than X. this comes with its own problems, as anybody knows who's had to debug problems where some things are overridden on the path and others aren't. Moreover, it has become a truism in the security community that using PATHs is a fruitful source of security holes. At the very least PATHs should not be imported from the user environment.

AndyGlew commented 1 week ago

IMHO things like this should be independent of what version control you are using. It's nice to know how to make something like this convenient with git.

jaresty commented 1 week ago

Yep. I agree that this isn't the solution I prefer. It's the best currently available unless you want to fork community. For people who are already using forks, though, there's little incentive to fix this-they're already used to maintaining their own configuration and integrating upstream changes periodically. I am sympathetic to your argument. It is going to take a lot to effect the change you are asking for, however.