Config (r)evolution #499

Closed
The-Compiler opened this Issue Feb 2, 2015 · 106 comments

Comments

Projects
@The-Compiler
Collaborator

The-Compiler commented Feb 2, 2015

Having the config in an .ini-like format might be a bad idea. Things like per-domain configs would probably be a lot easier in YAML...

Some links:


See this proposal for more information about what the exact plans are for this.


Note: There's currently a Kickstarter campaign running with the goal of finally making this happen!

@The-Compiler The-Compiler self-assigned this Feb 2, 2015

@The-Compiler The-Compiler added this to the v0.2 milestone Feb 2, 2015

@pedromj

This comment has been minimized.

Show comment
Hide comment
@pedromj

pedromj Feb 3, 2015

I think this is a good idea but you have to "budget" the effort and weight it against the benefits.

pedromj commented Feb 3, 2015

I think this is a good idea but you have to "budget" the effort and weight it against the benefits.

@avelino

This comment has been minimized.

Show comment
Hide comment

avelino commented Feb 3, 2015

+1

The-Compiler added a commit that referenced this issue Feb 4, 2015

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Feb 4, 2015

Collaborator

I believe the effort is neglible if you put it in perspective with how many hours I've put into qutebrowser so far, and how many more I probably will. I still believe in using the best tool available for the task at hand - and I think now I realized there's a better tool, and it's much more future-proof for the config.

I started the sessions branch (see #12) and I decided I'll use yaml for the session files, as using ini for that is definitely too cumbersome. I'll get more familiar with yaml/PyYAML there, and if it feels right, I'll convert the config stuff to yaml as well after sessions are done.

Collaborator

The-Compiler commented Feb 4, 2015

I believe the effort is neglible if you put it in perspective with how many hours I've put into qutebrowser so far, and how many more I probably will. I still believe in using the best tool available for the task at hand - and I think now I realized there's a better tool, and it's much more future-proof for the config.

I started the sessions branch (see #12) and I decided I'll use yaml for the session files, as using ini for that is definitely too cumbersome. I'll get more familiar with yaml/PyYAML there, and if it feels right, I'll convert the config stuff to yaml as well after sessions are done.

The-Compiler added a commit that referenced this issue Feb 5, 2015

The-Compiler added a commit that referenced this issue Feb 8, 2015

@traverseda

This comment has been minimized.

Show comment
Hide comment
@traverseda

traverseda Feb 9, 2015

I personally like prettified json. It's generally not too painful to edit, it's dead simple, and if you use it via an import then it's a pretty good place to implement a bit of custom deployment logic. Instead of having settings.yaml or settings.json, you have a settings.py with some inline json.

It works fine for projects like django, scrapy, awesomewm... Really it depends on your target audience. If you're expecting mainly programmers, then I wouldn't expect there to be any problem with a .py config file, and you'd probably get clearer error messages.

I wouldn't mind taking a crack it it if you think it's a viable direction going forward.

I personally like prettified json. It's generally not too painful to edit, it's dead simple, and if you use it via an import then it's a pretty good place to implement a bit of custom deployment logic. Instead of having settings.yaml or settings.json, you have a settings.py with some inline json.

It works fine for projects like django, scrapy, awesomewm... Really it depends on your target audience. If you're expecting mainly programmers, then I wouldn't expect there to be any problem with a .py config file, and you'd probably get clearer error messages.

I wouldn't mind taking a crack it it if you think it's a viable direction going forward.

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Feb 9, 2015

Collaborator
Collaborator

The-Compiler commented Feb 9, 2015

@traverseda

This comment has been minimized.

Show comment
Hide comment
@traverseda

traverseda Feb 9, 2015

Makes sense to me.

Makes sense to me.

The-Compiler added a commit that referenced this issue Feb 15, 2015

The-Compiler added a commit that referenced this issue Feb 16, 2015

Add session support.
Closes #12.
See #499.
See #11.

This adds PyYAML as a new dependency.

It adds the following new commands:

    :session-delete <name>
    Delete a session.

    :session-load <name>
    Load a session.

    :session-save [<name>]
    Save a session.

    :wq [<name>]
    Save open pages and quit.

And the following new settings:

    general -> save-session:
    Whether to always save the open pages.
@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Feb 18, 2015

Collaborator

It might also make sense to add some dependency to validate the structure of the yaml files.

Possibilities:

Collaborator

The-Compiler commented Feb 18, 2015

It might also make sense to add some dependency to validate the structure of the yaml files.

Possibilities:

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Feb 25, 2015

Collaborator

Retargeting this to v0.3 as I really want to get v0.2 out at some point...

Some ideas about the general structure:

config:
    foo: bar
    baz:
    - value
    - with
    - list
    - type
    ...

keys:
    d: close
    ...

domain http://www.qutebrowser.org/:
    config:
        foo: fish
    keys:
        bar: fish

Then we could also easily split the config into multiple files. It probably makes most sense to have a config.yml, keys.yml and perdomain.yml or so.

Collaborator

The-Compiler commented Feb 25, 2015

Retargeting this to v0.3 as I really want to get v0.2 out at some point...

Some ideas about the general structure:

config:
    foo: bar
    baz:
    - value
    - with
    - list
    - type
    ...

keys:
    d: close
    ...

domain http://www.qutebrowser.org/:
    config:
        foo: fish
    keys:
        bar: fish

Then we could also easily split the config into multiple files. It probably makes most sense to have a config.yml, keys.yml and perdomain.yml or so.

@The-Compiler The-Compiler modified the milestones: v0.3, v0.2 Feb 25, 2015

@Ram-Z

This comment has been minimized.

Show comment
Hide comment
@Ram-Z

Ram-Z Feb 25, 2015

Contributor

What about using a list for per-domain settings?

domains:
- qutebrowser.org:
    config:
      foo: fish
    keys:
      bar: fish
- .*\.google\.com:
    config: { foo: baz }
Contributor

Ram-Z commented Feb 25, 2015

What about using a list for per-domain settings?

domains:
- qutebrowser.org:
    config:
      foo: fish
    keys:
      bar: fish
- .*\.google\.com:
    config: { foo: baz }
@Ram-Z

This comment has been minimized.

Show comment
Hide comment
@Ram-Z

Ram-Z Feb 25, 2015

Contributor

I would prefer separate files.

Contributor

Ram-Z commented Feb 25, 2015

I would prefer separate files.

@noctuid

This comment has been minimized.

Show comment
Hide comment
@noctuid

noctuid May 13, 2015

YAML makes sense for sessions, but for configuration, I'd much prefer to be able to have a single init file that just contains qutebrowser commands. This is the way most interactive applications I am familiar with do things. Mutt, pentadactyl, vim (basically), and the shell are like this for example.

For one, it's consistent. bind would be used instead of the keys.conf format. quickmark-add and set would be used in the config file exactly as they would be used from the qutebrowser cmd mode. I'm not sure I see the benefit of an ini or yaml config file in the first place. Maybe it's easier (or prettier to look at for some) when creating the config file if the user modifies something like qute:settings, but even if YAML becomes the default, I think it would be nice if there was some way to have a file of qutebrowser commands sourced on initialization.

As for per-domain settings, pentadactyl does this with "groups." Every mapping is normally in the default group. After a group is defined with the group command, subsequent mappings are a part of that group (a specific domain) unless otherwise specified. -group can also be used explicitly with commands. The reason I bring this up is that I don't like the idea of having incompatability between what can be done in the initialization config and from a running qutebrowser. Is the plan to make per-domain settings/mappings tied exclusively to a yaml config so that they cannot be created from the qutebrowser commandline?

noctuid commented May 13, 2015

YAML makes sense for sessions, but for configuration, I'd much prefer to be able to have a single init file that just contains qutebrowser commands. This is the way most interactive applications I am familiar with do things. Mutt, pentadactyl, vim (basically), and the shell are like this for example.

For one, it's consistent. bind would be used instead of the keys.conf format. quickmark-add and set would be used in the config file exactly as they would be used from the qutebrowser cmd mode. I'm not sure I see the benefit of an ini or yaml config file in the first place. Maybe it's easier (or prettier to look at for some) when creating the config file if the user modifies something like qute:settings, but even if YAML becomes the default, I think it would be nice if there was some way to have a file of qutebrowser commands sourced on initialization.

As for per-domain settings, pentadactyl does this with "groups." Every mapping is normally in the default group. After a group is defined with the group command, subsequent mappings are a part of that group (a specific domain) unless otherwise specified. -group can also be used explicitly with commands. The reason I bring this up is that I don't like the idea of having incompatability between what can be done in the initialization config and from a running qutebrowser. Is the plan to make per-domain settings/mappings tied exclusively to a yaml config so that they cannot be created from the qutebrowser commandline?

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler May 13, 2015

Collaborator

Thanks for your input!

Maybe it's easier (or prettier to look at for some) when creating the config file if the user modifies something like qute:settings

This was the main motiviation indeed. With a config like you describe it, I can only think of these scenarios:

  • The config gets overwritten when the user uses the GUI to set something. Clearly not a good thing.
  • There's a separate file for the things set interactively, and it gets sourced before the "real" config. This might work...

I have to think a bit more about that idea though - coming from dwb (which does something similiar to what qutebrowser does now) I didn't even consider this. I definitely see the advantages.

I think there are some other caveats though, especially related to interactive settings and escaping of chars.

I think it would be nice if there was some way to have a file of qutebrowser commands sourced on initialization.

That's planned as a part of #35. That means even if I go for YAML, you could still not set things interactively (which keeps the file empty) and write such a file. 😄

Is the plan to make per-domain settings/mappings tied exclusively to a yaml config so that they cannot be created from the qutebrowser commandline?

No, I planned to add something like --domain to :set.

Collaborator

The-Compiler commented May 13, 2015

Thanks for your input!

Maybe it's easier (or prettier to look at for some) when creating the config file if the user modifies something like qute:settings

This was the main motiviation indeed. With a config like you describe it, I can only think of these scenarios:

  • The config gets overwritten when the user uses the GUI to set something. Clearly not a good thing.
  • There's a separate file for the things set interactively, and it gets sourced before the "real" config. This might work...

I have to think a bit more about that idea though - coming from dwb (which does something similiar to what qutebrowser does now) I didn't even consider this. I definitely see the advantages.

I think there are some other caveats though, especially related to interactive settings and escaping of chars.

I think it would be nice if there was some way to have a file of qutebrowser commands sourced on initialization.

That's planned as a part of #35. That means even if I go for YAML, you could still not set things interactively (which keeps the file empty) and write such a file. 😄

Is the plan to make per-domain settings/mappings tied exclusively to a yaml config so that they cannot be created from the qutebrowser commandline?

No, I planned to add something like --domain to :set.

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler May 13, 2015

Collaborator

I just discussed with some people in the #archlinux IRC channel.

It probably would make sense to have separate config files for things set by the user vs. things set in the GUI.

Then the GUI config gets auto-migration etc., and the user config never gets touched. Novice users will just use the GUI, and more experienced users will write their own config file (which is initially empty).

As for precedence, I think the user config should win, because removing something from the gui config after it's been added might be tricky and surprising.

Collaborator

The-Compiler commented May 13, 2015

I just discussed with some people in the #archlinux IRC channel.

It probably would make sense to have separate config files for things set by the user vs. things set in the GUI.

Then the GUI config gets auto-migration etc., and the user config never gets touched. Novice users will just use the GUI, and more experienced users will write their own config file (which is initially empty).

As for precedence, I think the user config should win, because removing something from the gui config after it's been added might be tricky and surprising.

@NoSuck

This comment has been minimized.

Show comment
Hide comment
@NoSuck

NoSuck May 13, 2015

That sounds like a good compromise, as the users who are more likely to edit config files in text tend to be the same users that would gripe when hand-edited configs are overridden by auto-migration.

NoSuck commented May 13, 2015

That sounds like a good compromise, as the users who are more likely to edit config files in text tend to be the same users that would gripe when hand-edited configs are overridden by auto-migration.

@noctuid

This comment has been minimized.

Show comment
Hide comment
@noctuid

noctuid May 14, 2015

No, I planned to add something like --domain to :set.

Sounds great!

It probably would make sense to have separate config files

I agree; that sounds perfect. I particularly like the idea of it being empty at first. In config files meant for the user, I prefer being able to only override or add to the default configuration instead of having to have all configuration/mappings (even if they haven't been altered) in the file. The suggested precedence makes sense as well.

noctuid commented May 14, 2015

No, I planned to add something like --domain to :set.

Sounds great!

It probably would make sense to have separate config files

I agree; that sounds perfect. I particularly like the idea of it being empty at first. In config files meant for the user, I prefer being able to only override or add to the default configuration instead of having to have all configuration/mappings (even if they haven't been altered) in the file. The suggested precedence makes sense as well.

@Al-Caveman

This comment has been minimized.

Show comment
Hide comment
@Al-Caveman

Al-Caveman Apr 22, 2017

Contributor

Aftrer reading this, I have some suggestions:

General config styles

I think it's better to drop this:

As many errors as possible are catched before python would throw an exception, e.g. arguments are explicitly type-checked. While this is unpythonic, it makes things easier for users not used to python.

And, instead, adopt a lazy behaviour, where qutebrowser handles errors (e.g. exists) as it reads the configs, without buffering.

While buffering errors may help a user solve his/her "many" errors a bit faster, such errors happen rarely anyway. Plus, it's unlikely that there are too many nested errors. E.g. usually, we use qutebrowser to browse the Internet.

Therefore, since errors are not a frequent thing, I think it is not worth optimizing for. So not worth increasing code complexity IMO, even if it's little complexity.

Change:

config.set(setting, value, domain=None)

To:

config.setting(value, group=None)
where setting is a placeholder for whatever settings that are available for tweaking.

Add:

config.url_to_group_mapper(f)

where f is a user defined function.

I think it's better to drop this feature:

with config.domain('qutebrowser.org'):
        config.set('key1, 'val1')
        config.set('key2, 'val2')

IMO, all configurations better consistently follow this single style:

config.<setting>(value, group=None)

IMO let group=None by default, and config.url_to_group_mapper by default is configured as follows:
config.url_to_group_mapper(f=[lambda url: None])
This way people who don't wish to use per-domain/group settings, they can simply ignore the group parameter, and write their configs as follows:
config.(value)

Different forms of configuration files

I think it's also better to drop all forms of other configurations, and keep only a single one (python).

If anyone wants YAML, RC, etc, then we can add separate modules that update the object config by parsing YAML/RC as follows:

load_yaml(config, 'file.yml')

Or:

load_rc(config, 'file.yml')

For example, for RC lovers, the config.py would have:

from qutebrowser.config.configapi import ConfigAPI
import load_rc # a separate module, that's possibly maintained outside of the project tree of qutebrowser.
config = ConfigAPI()
load_rc(config, "/path/to/whetever/they/love/their/rc/config/to/be/qute.rc")

Should Qutebrowser update configs automatically?

I suggest no, but I also suggest the following:

  • In any config.py file, there must be a variable named version.
  • Qutebrowser checks version, and compares it against its current version.
  • If there is a version mismatch:
    • Qutebrowser shows a warning.
    • Qutebrowser writes config.py.new.

Then the user is expected to take advantage of config.py.new to migrate the settings manually. Once the user completes the migration, he will have his version=... variable updated, and that warning will disappear.

Contributor

Al-Caveman commented Apr 22, 2017

Aftrer reading this, I have some suggestions:

General config styles

I think it's better to drop this:

As many errors as possible are catched before python would throw an exception, e.g. arguments are explicitly type-checked. While this is unpythonic, it makes things easier for users not used to python.

And, instead, adopt a lazy behaviour, where qutebrowser handles errors (e.g. exists) as it reads the configs, without buffering.

While buffering errors may help a user solve his/her "many" errors a bit faster, such errors happen rarely anyway. Plus, it's unlikely that there are too many nested errors. E.g. usually, we use qutebrowser to browse the Internet.

Therefore, since errors are not a frequent thing, I think it is not worth optimizing for. So not worth increasing code complexity IMO, even if it's little complexity.

Change:

config.set(setting, value, domain=None)

To:

config.setting(value, group=None)
where setting is a placeholder for whatever settings that are available for tweaking.

Add:

config.url_to_group_mapper(f)

where f is a user defined function.

I think it's better to drop this feature:

with config.domain('qutebrowser.org'):
        config.set('key1, 'val1')
        config.set('key2, 'val2')

IMO, all configurations better consistently follow this single style:

config.<setting>(value, group=None)

IMO let group=None by default, and config.url_to_group_mapper by default is configured as follows:
config.url_to_group_mapper(f=[lambda url: None])
This way people who don't wish to use per-domain/group settings, they can simply ignore the group parameter, and write their configs as follows:
config.(value)

Different forms of configuration files

I think it's also better to drop all forms of other configurations, and keep only a single one (python).

If anyone wants YAML, RC, etc, then we can add separate modules that update the object config by parsing YAML/RC as follows:

load_yaml(config, 'file.yml')

Or:

load_rc(config, 'file.yml')

For example, for RC lovers, the config.py would have:

from qutebrowser.config.configapi import ConfigAPI
import load_rc # a separate module, that's possibly maintained outside of the project tree of qutebrowser.
config = ConfigAPI()
load_rc(config, "/path/to/whetever/they/love/their/rc/config/to/be/qute.rc")

Should Qutebrowser update configs automatically?

I suggest no, but I also suggest the following:

  • In any config.py file, there must be a variable named version.
  • Qutebrowser checks version, and compares it against its current version.
  • If there is a version mismatch:
    • Qutebrowser shows a warning.
    • Qutebrowser writes config.py.new.

Then the user is expected to take advantage of config.py.new to migrate the settings manually. Once the user completes the migration, he will have his version=... variable updated, and that warning will disappear.

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Apr 22, 2017

Collaborator

I've said a lot on this subject, so I just want to make it known I've come around to @The-Compiler 's priorities: do whatever keeps the code and the logic simple, users will adapt to it. :)

I wouldn't say that's true, that's more the case with suckless surf which in turn isn't really usable IMHO 😛 - as mentioned above, I'm mainly worried about the complexity for users there. Or as the Zen of Python puts it: "If the implementation is hard to explain, it's a bad idea." 😉

I think it's better to drop this:

As many errors as possible are catched before python would throw an exception, e.g. arguments are explicitly type-checked. While this is unpythonic, it makes things easier for users not used to python.

And, instead, adopt a lazy behaviour, where qutebrowser handles errors (e.g. exists) as it reads the configs, without buffering.

This wasn't about buffering errors, but about giving useful error messages.

Change:

config.set(setting, value, domain=None)

To:

config.setting(value, group=None)
where setting is a placeholder for whatever settings that are available for tweaking.

I actually like the suggestion you made above where the settings are just
attributes. I need to think about that some more. Having them be callables (i.e.
config.colors.statusbar('#fffff')) seems odd to me, and not really needed.

Add:

config.url_to_group_mapper(f)

where f is a user defined function.

I think it's better to drop this feature:

with config.domain('qutebrowser.org'):
        config.set('key1, 'val1')
        config.set('key2, 'val2')

IMO, all configurations better consistently follow this single style:

config.<setting>(value, group=None)

IMO let group=None by default, and config.url_to_group_mapper by default is configured as follows:
config.url_to_group_mapper(f=[lambda url: None])
This way people who don't wish to use per-domain/group settings, they can simply ignore the group parameter, and write their configs as follows:
config.(value)

This sounds much too complicated - I don't see what's wrong with my with config.domain('qutebrowser.org'): example above, or what would be better (or simpler) with your proposal.

I think it's also better to drop all forms of other configurations, and keep only a single one (python).

That means there's no way to configure things via qutebrowser's GUI anymore, and
that's not going to happen. In particular, this also means there wouldn't be a
simple keybinding to toggle e.g. javascript permissions.

For example, for RC lovers, the config.py would have:

from qutebrowser.config.configapi import ConfigAPI
import load_rc
config = ConfigAPI()
load_rc(config, "/path/to/whetever/they/love/their/rc/config/to/be/qute.rc")

If an RC-like format would be implemented, I also tend towards something like this. However, as said above, I'm not convinced anymore that it's a good idea (and @lahwaacz makes a good point about adding this at a later time, if at all).

Collaborator

The-Compiler commented Apr 22, 2017

I've said a lot on this subject, so I just want to make it known I've come around to @The-Compiler 's priorities: do whatever keeps the code and the logic simple, users will adapt to it. :)

I wouldn't say that's true, that's more the case with suckless surf which in turn isn't really usable IMHO 😛 - as mentioned above, I'm mainly worried about the complexity for users there. Or as the Zen of Python puts it: "If the implementation is hard to explain, it's a bad idea." 😉

I think it's better to drop this:

As many errors as possible are catched before python would throw an exception, e.g. arguments are explicitly type-checked. While this is unpythonic, it makes things easier for users not used to python.

And, instead, adopt a lazy behaviour, where qutebrowser handles errors (e.g. exists) as it reads the configs, without buffering.

This wasn't about buffering errors, but about giving useful error messages.

Change:

config.set(setting, value, domain=None)

To:

config.setting(value, group=None)
where setting is a placeholder for whatever settings that are available for tweaking.

I actually like the suggestion you made above where the settings are just
attributes. I need to think about that some more. Having them be callables (i.e.
config.colors.statusbar('#fffff')) seems odd to me, and not really needed.

Add:

config.url_to_group_mapper(f)

where f is a user defined function.

I think it's better to drop this feature:

with config.domain('qutebrowser.org'):
        config.set('key1, 'val1')
        config.set('key2, 'val2')

IMO, all configurations better consistently follow this single style:

config.<setting>(value, group=None)

IMO let group=None by default, and config.url_to_group_mapper by default is configured as follows:
config.url_to_group_mapper(f=[lambda url: None])
This way people who don't wish to use per-domain/group settings, they can simply ignore the group parameter, and write their configs as follows:
config.(value)

This sounds much too complicated - I don't see what's wrong with my with config.domain('qutebrowser.org'): example above, or what would be better (or simpler) with your proposal.

I think it's also better to drop all forms of other configurations, and keep only a single one (python).

That means there's no way to configure things via qutebrowser's GUI anymore, and
that's not going to happen. In particular, this also means there wouldn't be a
simple keybinding to toggle e.g. javascript permissions.

For example, for RC lovers, the config.py would have:

from qutebrowser.config.configapi import ConfigAPI
import load_rc
config = ConfigAPI()
load_rc(config, "/path/to/whetever/they/love/their/rc/config/to/be/qute.rc")

If an RC-like format would be implemented, I also tend towards something like this. However, as said above, I'm not convinced anymore that it's a good idea (and @lahwaacz makes a good point about adding this at a later time, if at all).

@lahwaacz

This comment has been minimized.

Show comment
Hide comment
@lahwaacz

lahwaacz Apr 22, 2017

Collaborator

I actually like the suggestion you made above where the settings are just
attributes. I need to think about that some more. Having them be callables (i.e.
config.colors.statusbar('#fffff')) seems odd to me, and not really needed.

Yep, config.colors.statusbar = '#ffffff' is what I'd expect. If other optional arguments for the assignment operator/function are needed, that could be implemented with the context manager syntax: config.set(setting, value, domain='qutebrowser.org') would be replaced with

with config.domain('qutebrowser.org'):
    config.setting = value

This sounds much too complicated - I don't see what's wrong with my with config.domain('qutebrowser.org'): example above, or what would be better (or simpler) with your proposal.

One notable difference is that @Al-Caveman used group instead of domain, probably with the intention to match multiple domains at once?

Collaborator

lahwaacz commented Apr 22, 2017

I actually like the suggestion you made above where the settings are just
attributes. I need to think about that some more. Having them be callables (i.e.
config.colors.statusbar('#fffff')) seems odd to me, and not really needed.

Yep, config.colors.statusbar = '#ffffff' is what I'd expect. If other optional arguments for the assignment operator/function are needed, that could be implemented with the context manager syntax: config.set(setting, value, domain='qutebrowser.org') would be replaced with

with config.domain('qutebrowser.org'):
    config.setting = value

This sounds much too complicated - I don't see what's wrong with my with config.domain('qutebrowser.org'): example above, or what would be better (or simpler) with your proposal.

One notable difference is that @Al-Caveman used group instead of domain, probably with the intention to match multiple domains at once?

@AeliusSaionji

This comment has been minimized.

Show comment
Hide comment
@AeliusSaionji

AeliusSaionji Apr 22, 2017

Contributor

but suckless is great! And yeah I lazily (incorrectly) worded my response, I do agree with you.

Contributor

AeliusSaionji commented Apr 22, 2017

but suckless is great! And yeah I lazily (incorrectly) worded my response, I do agree with you.

@noctuid

This comment has been minimized.

Show comment
Hide comment
@noctuid

noctuid Apr 22, 2017

I'm not saying it doesn't have any benefits over a config.py, but I also don't think it's a good idea to have three config files which more or less do the same thing.

They would each serve a different purpose, and the first is storage only anyway. What exactly is the downside?

Given how different qutebrowser's command line is from anything you might be familiar with (see #2017 and the issues linked from there), it's not true that the config.rc syntax does not require much explanation or that it is intuitive and simple.

It would not require any additional explanation is my point. The command line needs to be documented whether or not config.rc syntax exists. Issues with the command line are issues with the command line, and whether it should be improved is a separate issue from whether the config.rc syntax should exist. What I was referring to as simple and intuitive is not qutebrowser's command line syntax but allowing a program to be configured in the same way in its configuration file as in its command line. I agree that it is sensible to wait for the command line syntax to stabilize though.

noctuid commented Apr 22, 2017

I'm not saying it doesn't have any benefits over a config.py, but I also don't think it's a good idea to have three config files which more or less do the same thing.

They would each serve a different purpose, and the first is storage only anyway. What exactly is the downside?

Given how different qutebrowser's command line is from anything you might be familiar with (see #2017 and the issues linked from there), it's not true that the config.rc syntax does not require much explanation or that it is intuitive and simple.

It would not require any additional explanation is my point. The command line needs to be documented whether or not config.rc syntax exists. Issues with the command line are issues with the command line, and whether it should be improved is a separate issue from whether the config.rc syntax should exist. What I was referring to as simple and intuitive is not qutebrowser's command line syntax but allowing a program to be configured in the same way in its configuration file as in its command line. I agree that it is sensible to wait for the command line syntax to stabilize though.

@Al-Caveman

This comment has been minimized.

Show comment
Hide comment
@Al-Caveman

Al-Caveman Apr 23, 2017

Contributor

@The-Compiler
I agree on callables. How about this one, where a setting becomes "per-domain" only if its type is a dictionary:

from qutebrowser.config.configapi import ConfigAPI

config = ConfigAPI()
config.hints.border = "1px solid #E3BE23"
config.hints.mode = {"gmail.com":"number", "yahoo.com":"letters"}
config.searchengines["gw"] = "https://google.com/q={}"
config.aliases["proxysocks"] = "set network proxy socks://127.0.0.1:9050"
config.ui.keyhint_delay = 0
config.command["wo"] = ":open -s {url}"

For example, say, config.hints.border and config.command["wo"] are examples of default settings that applies to all domains. On the other hand, since type(config.hints.mode)==dict is True, then config.hints.mode is a per-domain setting, where its key represents the domain, and its value represents the setting value for that specific domain.

Here is another example, except for using groups (1 and 2) instead of domains:

from qutebrowser.config.configapi import ConfigAPI

config = ConfigAPI()
config.hints.border = "1px solid #E3BE23"
config.hints.mode = {1:"number", 2:"letters"}
config.searchengines["gw"] = "https://google.com/q={}"
config.aliases["proxysocks"] = "set network proxy socks://127.0.0.1:9050"
config.ui.keyhint_delay = 0
config.command["wo"] = ":open -s {url}"
config.domain_to_group_map = f

def f(domain, group):
    if "gmail.com" in domain:
        return 2
    else:
        return 1

I think, if there are no technical limitations, it is better to pass URLs instead of domains, so that the domain becomes only a special case of the URL and achieve more flexibility. E.g.

from qutebrowser.config.configapi import ConfigAPI
import re

config = ConfigAPI()
config.hints.border = "1px solid #E3BE23"
config.hints.mode = {1:"number", 2:"letters"}
config.searchengines["gw"] = "https://google.com/q={}"
config.aliases["proxysocks"] = "set network proxy socks://127.0.0.1:9050"
config.ui.keyhint_delay = 0
config.command["wo"] = ":open -s {url}"
config.url_to_group_map = f

def f(url, group):
    if re.match(r'^https?://.*?.com/.*var=popup#test', url):
        return 2
    else:
        return 1

@lahwaacz

One notable difference is that @Al-Caveman used group instead of domain, probably with the intention to match multiple domains at once?

I don't know what "match multiple domains at once" means. Maybe I accidentally suggested something better without realizing it. Could you please clarify this?

Personally, my reason was based on my intuition that there are more domains than there are "categories of treatment". So it's more convenient for us to define groups of treatments (settings), and then assign the domains (or URLs) to those groups.

My other reason was, once we swallow the idea of groups, another problem is: should we map domains one by one against their groups? I think this is also another inconvenience. This is why I suggested a mapping function, because the function could effectively generalize a mappin rule, so that we could potentially put heuristics there, and end up classifying many Internet websites, without having to explecitly list their domains or URLs.

For example, my example above allowed to map any domain based on the domain-agnostic regexp rule: ^https?://.*?.com/.*var=popup#test.


Note: Of course, I am possibly wrong about this. I hope that my long posts don't give the impression that I'm strongly pushing for this. Not that it matters, but just thought to clarify. It's just my opinion, and even I'm not sure about my ideas. It looks foggy to me. I just shared them in case some wiser being can make some wiser decision out of it :D.

Personaly, my main concern with my ideas is speed (it's not a pressing issue, but I don't want another Pentadactyle; with all respect, I really like qutebrowser's fast responsiveness). I wonder if calling those mapping methods will be too expensive? I wonder if there is a plan to index those per-domain/URL settings so that it doesn't become too slow? I hope my concerns are false.

Contributor

Al-Caveman commented Apr 23, 2017

@The-Compiler
I agree on callables. How about this one, where a setting becomes "per-domain" only if its type is a dictionary:

from qutebrowser.config.configapi import ConfigAPI

config = ConfigAPI()
config.hints.border = "1px solid #E3BE23"
config.hints.mode = {"gmail.com":"number", "yahoo.com":"letters"}
config.searchengines["gw"] = "https://google.com/q={}"
config.aliases["proxysocks"] = "set network proxy socks://127.0.0.1:9050"
config.ui.keyhint_delay = 0
config.command["wo"] = ":open -s {url}"

For example, say, config.hints.border and config.command["wo"] are examples of default settings that applies to all domains. On the other hand, since type(config.hints.mode)==dict is True, then config.hints.mode is a per-domain setting, where its key represents the domain, and its value represents the setting value for that specific domain.

Here is another example, except for using groups (1 and 2) instead of domains:

from qutebrowser.config.configapi import ConfigAPI

config = ConfigAPI()
config.hints.border = "1px solid #E3BE23"
config.hints.mode = {1:"number", 2:"letters"}
config.searchengines["gw"] = "https://google.com/q={}"
config.aliases["proxysocks"] = "set network proxy socks://127.0.0.1:9050"
config.ui.keyhint_delay = 0
config.command["wo"] = ":open -s {url}"
config.domain_to_group_map = f

def f(domain, group):
    if "gmail.com" in domain:
        return 2
    else:
        return 1

I think, if there are no technical limitations, it is better to pass URLs instead of domains, so that the domain becomes only a special case of the URL and achieve more flexibility. E.g.

from qutebrowser.config.configapi import ConfigAPI
import re

config = ConfigAPI()
config.hints.border = "1px solid #E3BE23"
config.hints.mode = {1:"number", 2:"letters"}
config.searchengines["gw"] = "https://google.com/q={}"
config.aliases["proxysocks"] = "set network proxy socks://127.0.0.1:9050"
config.ui.keyhint_delay = 0
config.command["wo"] = ":open -s {url}"
config.url_to_group_map = f

def f(url, group):
    if re.match(r'^https?://.*?.com/.*var=popup#test', url):
        return 2
    else:
        return 1

@lahwaacz

One notable difference is that @Al-Caveman used group instead of domain, probably with the intention to match multiple domains at once?

I don't know what "match multiple domains at once" means. Maybe I accidentally suggested something better without realizing it. Could you please clarify this?

Personally, my reason was based on my intuition that there are more domains than there are "categories of treatment". So it's more convenient for us to define groups of treatments (settings), and then assign the domains (or URLs) to those groups.

My other reason was, once we swallow the idea of groups, another problem is: should we map domains one by one against their groups? I think this is also another inconvenience. This is why I suggested a mapping function, because the function could effectively generalize a mappin rule, so that we could potentially put heuristics there, and end up classifying many Internet websites, without having to explecitly list their domains or URLs.

For example, my example above allowed to map any domain based on the domain-agnostic regexp rule: ^https?://.*?.com/.*var=popup#test.


Note: Of course, I am possibly wrong about this. I hope that my long posts don't give the impression that I'm strongly pushing for this. Not that it matters, but just thought to clarify. It's just my opinion, and even I'm not sure about my ideas. It looks foggy to me. I just shared them in case some wiser being can make some wiser decision out of it :D.

Personaly, my main concern with my ideas is speed (it's not a pressing issue, but I don't want another Pentadactyle; with all respect, I really like qutebrowser's fast responsiveness). I wonder if calling those mapping methods will be too expensive? I wonder if there is a plan to index those per-domain/URL settings so that it doesn't become too slow? I hope my concerns are false.

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Apr 23, 2017

Collaborator

I'd still rather stay with the context manager syntax (with config.domain(...):) and instead allow regexes (or glob patterns, not sure regexes really make sense) there.

Something like:

with config.domain(r'/pattern/'):
    config.hints.mode = 'number'

or:

with config.domain(re.compile(r'pattern')):
    config.hints.mode = 'number'

For multiple domains, this might be a possibility:

with config.domains('www.example.com', 'www.example.org'):
    ...

Having a dict as type is already needed for actual setting values, e.g. for network -> custom-headers.

As for URLs versus domains: Some settings will only work on domain (i.e. host) level - some might be technically possible to have on an URL level, but that again leads to more complexity (mostly for the user, some in the code) which I'm not sure is actually needed. Time will tell 😉

Collaborator

The-Compiler commented Apr 23, 2017

I'd still rather stay with the context manager syntax (with config.domain(...):) and instead allow regexes (or glob patterns, not sure regexes really make sense) there.

Something like:

with config.domain(r'/pattern/'):
    config.hints.mode = 'number'

or:

with config.domain(re.compile(r'pattern')):
    config.hints.mode = 'number'

For multiple domains, this might be a possibility:

with config.domains('www.example.com', 'www.example.org'):
    ...

Having a dict as type is already needed for actual setting values, e.g. for network -> custom-headers.

As for URLs versus domains: Some settings will only work on domain (i.e. host) level - some might be technically possible to have on an URL level, but that again leads to more complexity (mostly for the user, some in the code) which I'm not sure is actually needed. Time will tell 😉

@lahwaacz

This comment has been minimized.

Show comment
Hide comment
@lahwaacz

lahwaacz Apr 23, 2017

Collaborator

The problem with regexes and globs is that they increase the complexity of the search. With plain strings like "qutebrowser.org" you could store them in a dict and have an O(1) search for domains, but with regexes you'd need to iterate over all regexes and for each one check if it matches the given domain/URL, so it's O(n). You'd actually need to do this to keep the config general, although in many cases the users' config might have one regex per domain and you'd have no way to optimize for that. I don't know how big the n might be in practice, but it's better to count with enough to make a noticeable difference on the browser's performance. In any case, the n will only get larger over time...

I came upon several ways to solve the matching more efficiently, but the most effective solution is to allow the regexes/globs in config.domain as shown above and have some lru_cache for the whole config objects holding the per-domain per-something settings. Also, I don't see the reason to match the full URL, IMO it would be enough to drop the path, query and fragment parts before matching, which would massively increase the efficiency of the cache.

Collaborator

lahwaacz commented Apr 23, 2017

The problem with regexes and globs is that they increase the complexity of the search. With plain strings like "qutebrowser.org" you could store them in a dict and have an O(1) search for domains, but with regexes you'd need to iterate over all regexes and for each one check if it matches the given domain/URL, so it's O(n). You'd actually need to do this to keep the config general, although in many cases the users' config might have one regex per domain and you'd have no way to optimize for that. I don't know how big the n might be in practice, but it's better to count with enough to make a noticeable difference on the browser's performance. In any case, the n will only get larger over time...

I came upon several ways to solve the matching more efficiently, but the most effective solution is to allow the regexes/globs in config.domain as shown above and have some lru_cache for the whole config objects holding the per-domain per-something settings. Also, I don't see the reason to match the full URL, IMO it would be enough to drop the path, query and fragment parts before matching, which would massively increase the efficiency of the cache.

@noctuid

This comment has been minimized.

Show comment
Hide comment
@noctuid

noctuid Apr 23, 2017

Having both with config.domain and domain= (and whatever way to match multiple urls/domains) seems perfect to me already.

not sure regexes really make sense

Also, I don't see the reason to match the full URL, IMO it would be enough to drop the path

I'd argue in favor of allowing regexes and the ability to match against the url including the path. I don't know about how useful url-specific settings would be, but the vast majority of my pentadactyl keybindings that use groups use globs/regexes to match specific urls. Some keybindings only make sense on specific pages of a website. On github, I match "blob" in the url and change my primary url copying keybinding to first send "y" (to change the url to be for the current commit). For sites that have pages that allow keyboard shortcuts by default (like gmail) or with userscripts, I will pass through certain keys only for those pages. I match certain file extensions (like 'png') to change certain keybindings such as those used to zoom and scroll. This doesn't work for every url that's an image, but it's often useful. The possibilities are endless. Sometimes globs are enough but not always in my experience (and sometimes pentadactyl's limited regex support is less than ideal), so I'd argue for regex support.

noctuid commented Apr 23, 2017

Having both with config.domain and domain= (and whatever way to match multiple urls/domains) seems perfect to me already.

not sure regexes really make sense

Also, I don't see the reason to match the full URL, IMO it would be enough to drop the path

I'd argue in favor of allowing regexes and the ability to match against the url including the path. I don't know about how useful url-specific settings would be, but the vast majority of my pentadactyl keybindings that use groups use globs/regexes to match specific urls. Some keybindings only make sense on specific pages of a website. On github, I match "blob" in the url and change my primary url copying keybinding to first send "y" (to change the url to be for the current commit). For sites that have pages that allow keyboard shortcuts by default (like gmail) or with userscripts, I will pass through certain keys only for those pages. I match certain file extensions (like 'png') to change certain keybindings such as those used to zoom and scroll. This doesn't work for every url that's an image, but it's often useful. The possibilities are endless. Sometimes globs are enough but not always in my experience (and sometimes pentadactyl's limited regex support is less than ideal), so I'd argue for regex support.

@NoctuaNivalis

This comment has been minimized.

Show comment
Hide comment
@NoctuaNivalis

NoctuaNivalis Apr 23, 2017

Contributor

The problem with regexes and globs is that they increase the complexity of the search.

It would, but I don't think it'd get too slow. I expect users to have at most 5 or 6 regex domain matchers.

I'd suggest the following syntax:

with config.domain_is('some.domain.com'):
    config.hints.mode = 'number'
with config.domain_matches(re.compile('pattern')):
    config.hints.mode = 'word'

As most settings are domain specific, you'd still have the constant time check for settings for the current domain.

Contributor

NoctuaNivalis commented Apr 23, 2017

The problem with regexes and globs is that they increase the complexity of the search.

It would, but I don't think it'd get too slow. I expect users to have at most 5 or 6 regex domain matchers.

I'd suggest the following syntax:

with config.domain_is('some.domain.com'):
    config.hints.mode = 'number'
with config.domain_matches(re.compile('pattern')):
    config.hints.mode = 'word'

As most settings are domain specific, you'd still have the constant time check for settings for the current domain.

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Apr 23, 2017

Collaborator

No need for a separate method - we could simply check whether we get a string or a compiled regex object.

I expect there to be a lot more lookups for per-domain javascript settings, but I guess you'd typically do them via the GUI (with a keybinding) in autoconfig.yml, and those can be O(1) (with a lookup per subdomain).

Collaborator

The-Compiler commented Apr 23, 2017

No need for a separate method - we could simply check whether we get a string or a compiled regex object.

I expect there to be a lot more lookups for per-domain javascript settings, but I guess you'd typically do them via the GUI (with a keybinding) in autoconfig.yml, and those can be O(1) (with a lookup per subdomain).

@AeliusSaionji

This comment has been minimized.

Show comment
Hide comment
@AeliusSaionji

AeliusSaionji Apr 30, 2017

Contributor

Actually, I do have one thing to say about configs: whatever you choose, I want to be able to source other config files from within my config.

In my personal dotfiles, I will have a qutebrowserconfig which contains nothing more than my deviations from default.

For example,

configitem1=true
configitem3=false
source /usr/share/qutebrowser/config

Please do not make me import an entire qutebrowser config into my git and then have me track/commit changes as the upstream config file changes.

Contributor

AeliusSaionji commented Apr 30, 2017

Actually, I do have one thing to say about configs: whatever you choose, I want to be able to source other config files from within my config.

In my personal dotfiles, I will have a qutebrowserconfig which contains nothing more than my deviations from default.

For example,

configitem1=true
configitem3=false
source /usr/share/qutebrowser/config

Please do not make me import an entire qutebrowser config into my git and then have me track/commit changes as the upstream config file changes.

@rcorre

This comment has been minimized.

Show comment
Hide comment
@rcorre

rcorre Apr 30, 2017

Collaborator

@Link-Satonaka: based on the proposal, there will no longer be a file pre-populated with all the settings:

By default, those files are missing/empty, and the built-in defaults get loaded

Collaborator

rcorre commented Apr 30, 2017

@Link-Satonaka: based on the proposal, there will no longer be a file pre-populated with all the settings:

By default, those files are missing/empty, and the built-in defaults get loaded

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Jun 6, 2017

Collaborator

What I haven't really talked about above is how the commands will look to edit some more complex setting types (like lists or dictionaries) from qutebrowser.

Things which used to be a section (like searchengines) will now be a dictionary, and the bindings probably will too. There are also various things like hints -> prev/next-regexes which will actually be stored as list.

My current idea how to handle this is to add a few new :config-* commands, with :set being an alias to :config-set because :set is just a common thing to have.

Setting

:config-set (aka :set) will take a JSON syntax to set the elements, and override any previous settings. Examples:

  • :set custom-headers '{"X-Answer": "42"}'

Adding

:config-add adds a new element to a dictionary or list.

Examples:

  • :config-add custom-headers X-Answer 42
  • :config-add searchengines wiki https://en.wikipedia.org/wiki/{}
  • :config-add next-regexes weiter

Removing

:config-remove removes an element by key (dicts) or value (lists).

Examples:

  • :config-remove custom-headers X-Answer
  • :config-remove searchengines wiki
  • :config-remove next-regexes weiter

Replacing

:config-replace searches an element as per above, and replaces the value.

Examples:

  • :config-replace custom-headers X-Answer 23
  • :config-replace searchengines wiki https://de.wikipedia.org/wiki/{}
  • :config-replace next-regexes weiter [Ww]eiter

Thoughts? Any other modifications which should be supported?

Collaborator

The-Compiler commented Jun 6, 2017

What I haven't really talked about above is how the commands will look to edit some more complex setting types (like lists or dictionaries) from qutebrowser.

Things which used to be a section (like searchengines) will now be a dictionary, and the bindings probably will too. There are also various things like hints -> prev/next-regexes which will actually be stored as list.

My current idea how to handle this is to add a few new :config-* commands, with :set being an alias to :config-set because :set is just a common thing to have.

Setting

:config-set (aka :set) will take a JSON syntax to set the elements, and override any previous settings. Examples:

  • :set custom-headers '{"X-Answer": "42"}'

Adding

:config-add adds a new element to a dictionary or list.

Examples:

  • :config-add custom-headers X-Answer 42
  • :config-add searchengines wiki https://en.wikipedia.org/wiki/{}
  • :config-add next-regexes weiter

Removing

:config-remove removes an element by key (dicts) or value (lists).

Examples:

  • :config-remove custom-headers X-Answer
  • :config-remove searchengines wiki
  • :config-remove next-regexes weiter

Replacing

:config-replace searches an element as per above, and replaces the value.

Examples:

  • :config-replace custom-headers X-Answer 23
  • :config-replace searchengines wiki https://de.wikipedia.org/wiki/{}
  • :config-replace next-regexes weiter [Ww]eiter

Thoughts? Any other modifications which should be supported?

@lamarpavel

This comment has been minimized.

Show comment
Hide comment
@lamarpavel

lamarpavel Jun 9, 2017

Contributor

Is the difference between :config-add and :config-replace just a check for existing entries?

Contributor

lamarpavel commented Jun 9, 2017

Is the difference between :config-add and :config-replace just a check for existing entries?

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Jun 9, 2017

Collaborator

@lamarpavel Hmm, good point - I guess it'd be fine for :config-add to just replace existing values. (so: yes)

Collaborator

The-Compiler commented Jun 9, 2017

@lamarpavel Hmm, good point - I guess it'd be fine for :config-add to just replace existing values. (so: yes)

@lamarpavel

This comment has been minimized.

Show comment
Hide comment
@lamarpavel

lamarpavel Jun 9, 2017

Contributor

Yeah, I think it would be better just to have :config-add, maybe with an (optional?) warning for existing entries.

Contributor

lamarpavel commented Jun 9, 2017

Yeah, I think it would be better just to have :config-add, maybe with an (optional?) warning for existing entries.

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Jun 9, 2017

Collaborator

Since this will be a breaking change, I'd also like to take the opportunity to reorganize the config to make things clearer - I'd really like some input on that! See #2708.

Collaborator

The-Compiler commented Jun 9, 2017

Since this will be a breaking change, I'd also like to take the opportunity to reorganize the config to make things clearer - I'd really like some input on that! See #2708.

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Jul 6, 2017

Collaborator

So this issue has gotten way too big - thanks for all your input! I've read through everything again, and then split it into smaller issues:

  • YAML config (autoconfig.yml): This is now implemented in the new-config branch. There'll still be some breaking changes, but it's by all means ready to play with, if you want to test it. It leaves your old config untouched. I'll also add a new post to the qutebrowser blog with a few more details.
  • Python config API: See #2795 (with a completely new API proposal)
  • config.rc: See #2796 (my stance is still "probably not going to happen", FWIW)
  • Per domain settings: See #27
  • New :config-* commands: See #2794 (with some new commands added)
  • Per tab/window settings: See #2314
Collaborator

The-Compiler commented Jul 6, 2017

So this issue has gotten way too big - thanks for all your input! I've read through everything again, and then split it into smaller issues:

  • YAML config (autoconfig.yml): This is now implemented in the new-config branch. There'll still be some breaking changes, but it's by all means ready to play with, if you want to test it. It leaves your old config untouched. I'll also add a new post to the qutebrowser blog with a few more details.
  • Python config API: See #2795 (with a completely new API proposal)
  • config.rc: See #2796 (my stance is still "probably not going to happen", FWIW)
  • Per domain settings: See #27
  • New :config-* commands: See #2794 (with some new commands added)
  • Per tab/window settings: See #2314
@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Sep 16, 2017

Collaborator

Quick update: The new-config branch is merged 🎉 A more detailed update will probably follow in the blog over the next few days.

Collaborator

The-Compiler commented Sep 16, 2017

Quick update: The new-config branch is merged 🎉 A more detailed update will probably follow in the blog over the next few days.

@Cloudef

This comment has been minimized.

Show comment
Hide comment
@Cloudef

Cloudef Dec 9, 2017

Can't say I'm happy with no tools for migrating the old configuration.
EDIT: Maybe there could be a python module to read the old configuration syntax from file and apply it?

Cloudef commented Dec 9, 2017

Can't say I'm happy with no tools for migrating the old configuration.
EDIT: Maybe there could be a python module to read the old configuration syntax from file and apply it?

@rcorre

This comment has been minimized.

Show comment
Hide comment
@rcorre

rcorre Dec 9, 2017

Collaborator

There is, if I remember correctly, a page that shows the diff between your config and the default config. It only took me a few minutes to port the diff to the new config, and the manual process helped me learn the new config syntax. I prefer that to having some generated file I don't understand.

Collaborator

rcorre commented Dec 9, 2017

There is, if I remember correctly, a page that shows the diff between your config and the default config. It only took me a few minutes to port the diff to the new config, and the manual process helped me learn the new config syntax. I prefer that to having some generated file I don't understand.

@mschilli87

This comment has been minimized.

Show comment
Hide comment
Contributor

mschilli87 commented Dec 9, 2017

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler Dec 9, 2017

Collaborator

An automatic migration also isn't really possible, as things changed in various ways (not only e.g. name changes), and the old config also had default setting values in it (plus defaults changed), so you can't really know automatically what the user intended to change and what not.

Collaborator

The-Compiler commented Dec 9, 2017

An automatic migration also isn't really possible, as things changed in various ways (not only e.g. name changes), and the old config also had default setting values in it (plus defaults changed), so you can't really know automatically what the user intended to change and what not.

@Cloudef

This comment has been minimized.

Show comment
Hide comment
@Cloudef

Cloudef Dec 9, 2017

@mschilli87 Yeah, I know about that. It helps, but there's quite a bit of those changes.
@The-Compiler I see, that's a bummer

Cloudef commented Dec 9, 2017

@mschilli87 Yeah, I know about that. It helps, but there's quite a bit of those changes.
@The-Compiler I see, that's a bummer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment