coBib’s New Configuration

4 minute read

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.

:scroll: 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

:warning: Notice, that the KEY_BINDINGS and COLORS sections have been moved into the TUI section. This was not possible in the INI-style configuration but is the more natural location for these settings to be in.