coBib’s New Configuration
coBib is getting a new configuration system with the next major release, version 3.0!
Although this release is by no means ready, I am already introducing the new configuration to build some other new features (which will also be part of v3.0) on top of it.
This means, if you are following coBib’s development branch, you will soon be presented with a warning when using coBib stating that the old INI
-style configuration is deprecated and a new Python-based one takes its place.
In this short post I will go over some of the reasons why I chose to re-design the configuration mechanism and provide you detailed instructions on how to migrate from the old INI
-style configuration.
Why use a Python-based configuration?
A configuration written in Python provides the user with the greatest flexibility to customize a program which is written in Python. Obviously, this power comes with responsibility, too. In theory, a user could monkey-patch the code to an almost uncontrollable degree, so care just be taken not to copy code into your configuration which you do not understand. Nonetheless, if the user is aware of this responsibility, the power which a Python-based configuration brings to the table is too great of an opportunity to miss out on for coBib.
When re-designing the configuration module I was looking for inspiration in the code of other Python-configured programs which I use myself, too. Namely, qtile and qutebrowser were the two codes which I was mainly looking into. However, I found that both of them (being much larger codes than coBib) had added a lot of code for the configuration parsing which I did not seem to require. Thus, in the end, I ended up with an implementation much different to either of their approaches.
I am not going to go into the details of how I implemented coBib’s new configuration but it essentially boils down to creating a ModuleSpec
from the location of the configuration file using importlib.util
.
I then combined this functionality with an easy-to-use extension of Python’s dict
class which allows recursive setting of items via attributes.
(See also this Stackoverflow answer.)
How to migrate my existing configuration?
Let me now focus on how you can convert your existing INI
-style configuration into a new Python-based one.
A short note before we get started: if you do not have an existing configuration, yet, the easiest way to get you started is to copy the well-documented example configuration to the default location and start adapting it to your needs. You can do so with the following command:
cobib _example_config > ~/.config/cobib/config.py
However, if you do have an existing configuration it is probably easier to continue reading and migrate it manually.
To get started, open the file ~/.config/cobib/config.py
in your text editor of choice.
At the top of the file, you have to import coBib’s configuration object:
1
from cobib.config import config
If you are wondering how you can import coBib’s configuration now, before you have written it, you can think of this step as loading the default configuration which you are now free to adapt to your liking.
In the rest of the file, you can now set the configuration options.
As mentioned before, coBib’s config
object is an extension of a dict
object.
Thus, the following two statements are equivalent:
1
2
config['database']['git'] = True
config.database.git = True
I personally find the latter to be more convenient for this particular use-case which is why I have added this attribute-setter capability.
If you want to find out what settings exist you can check out coBib’s man-page (man cobib
) or the example configuration cobib _example_config
).
Before I leave you to it, you should know that coBib will validate your configuration before using it.
Thus, if you experience an error be sure to read the output as it will likely tell you which setting is causing a problem (e.g. an invalid type).
Finally, here is a comparison of the old and new settings. As you will see, some of the settings have been renamed/moved (these are highlighted in bold).
Old | New |
---|---|
DATABASE.file | config.database.file |
DATABASE.git | config.database.git |
DATABASE.open | config.commands.open.command |
DATABASE.grep | config.commands.search.grep |
DATABASE.search_ignore_case | config.commands.search.ignore_case |
FORMAT.month | config.database.format.month |
FORMAT.ignore_non_standard_types | config.parsers.bibtex.ignore_non_standard_types |
FORMAT.default_entry_type | config.commands.edit.default_entry_type |
TUI.default_list_args | config.tui.default_list_args |
TUI.prompt_before_quit | config.tui.prompt_before_quit |
TUI.reverse_order | config.tui.reverse_order |
TUI.scroll_offset | config.tui.scroll_offset |
KEY_BINDINGS.Add | config.tui.key_bindings.add |
KEY_BINDINGS.Delete | config.tui.key_bindings.delete |
KEY_BINDINGS.Edit | config.tui.key_bindings.edit |
KEY_BINDINGS.Export | config.tui.key_bindings.export |
KEY_BINDINGS.Filter | config.tui.key_bindings.filter |
KEY_BINDINGS.Help | config.tui.key_bindings.help |
KEY_BINDINGS.Modify | config.tui.key_bindings.modify |
KEY_BINDINGS.Open | config.tui.key_bindings.open |
KEY_BINDINGS.Prompt | config.tui.key_bindings.prompt |
KEY_BINDINGS.Quit | config.tui.key_bindings.quit |
KEY_BINDINGS.Redo | config.tui.key_bindings.redo |
KEY_BINDINGS.Search | config.tui.key_bindings.search |
KEY_BINDINGS.Select | config.tui.key_bindings.select |
KEY_BINDINGS.Show | config.tui.key_bindings.show |
KEY_BINDINGS.Sort | config.tui.key_bindings.sort |
KEY_BINDINGS.Undo | config.tui.key_bindings.undo |
KEY_BINDINGS.Wrap | config.tui.key_bindings.wrap |
COLORS.cursor_line_fg | config.tui.colors.cursor_line_fg |
COLORS.cursor_line_bg | config.tui.colors.cursor_line_bg |
COLORS.top_statusbar_fg | config.tui.colors.top_statusbar_fg |
COLORS.top_statusbar_bg | config.tui.colors.top_statusbar_bg |
COLORS.bottom_statusbar_fg | config.tui.colors.bottom_statusbar_fg |
COLORS.bottom_statusbar_bg | config.tui.colors.bottom_statusbar_bg |
COLORS.search_label_fg | config.tui.colors.search_label_fg |
COLORS.search_label_bg | config.tui.colors.search_label_bg |
COLORS.search_query_fg | config.tui.colors.search_query_fg |
COLORS.search_query_bg | config.tui.colors.search_query_bg |
COLORS.popup_help_fg | config.tui.colors.popup_help_fg |
COLORS.popup_help_bg | config.tui.colors.popup_help_bg |
COLORS.popup_stdout_fg | config.tui.colors.popup_stdout_fg |
COLORS.popup_stdout_bg | config.tui.colors.popup_stdout_bg |
COLORS.popup_stderr_fg | config.tui.colors.popup_stderr_fg |
COLORS.popup_stderr_bg | config.tui.colors.popup_stderr_bg |
COLORS.selection_fg | config.tui.colors.selection_fg |
COLORS.selection_bg | config.tui.colors.selection_bg |
Notice, that the
KEY_BINDINGS
andCOLORS
sections have been moved into theTUI
section. This was not possible in theINI
-style configuration but is the more natural location for these settings to be in.