prompt-toolkit / ptpython

A better Python REPL
BSD 3-Clause "New" or "Revised" License
5.22k stars 278 forks source link

Feature request: have a config file #232

Open jpz opened 6 years ago

jpz commented 6 years ago

For example, I want to set up a simple text-file-based config to set the default editor to vim.

At present I need maintain 150+ lines of python to keep basic config under control.

On another note, I see there isn't a release for 6 months, and a large issue backlog.

I think this is a fantastic project, and maybe you as the author might consider releasing the code into a ptpython org and selecting a group of maintainers to assist you with miantaining the backlog?

I think the project has every chance of becoming commonly adopted, if enough people were to be able to chip in and help polish small usability bits and pieces, such as (for example) the issue I mention above. Related to my issue, for instance, is the fact that the only way to find out how to configure it is to read the github repo - and that will be a barrier to wide-spread adoption for the average user.

cometsong commented 5 years ago

I set up my own rendition of the configure function for this type of config.

Inside my Python startup script (.pythonrc.py) I pasted this:

# PTPython Config:
def configure(repl, config_file=None):
    """
    Configuration method. This is called during the start-up of ptpython.
    Default configuration settings are here, and can be modified by entries
    in a TOML file if desired for local or general use.

    :param repl: `PythonRepl` instance.
    :config_file: TOML text file with configuration
    """

    def read_config_file(toml_file):
        """read config settings from TOML file"""
        try:
            from toml import load
        except ImportError:
            return {"config_file_error":
                    "'toml' module must be installed to use config file"}
        else:
            return load(toml_file)

    if not config_file: # use default config.toml path:
        config_file = '~/.ptpython/config.toml'
        config_file = os.path.expanduser(config_file)

    if os.path.exists(config_file):
        configs = read_config_file(config_file)

        comp_vis = configs.get('completion_visualisation', 'POP_UP')
        configs['completion_visualisation'] = \
            getattr(CompletionVisualisation, comp_vis)

        code_colorscheme = configs.pop('use_code_colorscheme', None)
        if code_colorscheme:
            repl.use_code_colorscheme(code_colorscheme)

        # Set all the  other attributes:
        for opt, val in configs.items():
            setattr(repl, opt, val)
    else:
        print('Impossible to read %r' % config_file)
        return

try:
    from ptpython.repl import embed
    from ptpython.layout import CompletionVisualisation
except ImportError:
    print("ptpython is not available: falling back to standard prompt")
except Exception as e:
    raise e
else:
    sys.exit(
        embed(globals(), locals()
              , history_filename=HISTFILE
              , configure=configure
              )
    )

The HISTFILE bit is one you can choose the path of or just leave out that line of course.

My ~/.ptpython/config.toml file has the same actual variables from the config.py, reformatted to use the 'standard' TOML format with equals signs and the [true|false] made lowercase.

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#             Configuration example file for `ptpython`.             #
#             Copy this file to ~/.ptpython/config.toml              #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

# Show function signature (bool).
show_signature = true

# Show completions. (NONE, POP_UP, MULTI_COLUMN or TOOLBAR)
completion_visualisation = 'POP_UP'

# When CompletionVisualisation.POP_UP has been chosen, use this
# scroll_offset in the completion menu.
completion_menu_scroll_offset = 0

# Show line numbers (when the input contains multiple lines.)
show_line_numbers = true

# ....
danieldjewell commented 4 years ago

I'll definitely +1 this - just trying out ptpython for the first time and I thought to myself "Oh wow, the config file is ... a Python script? Well, I guess that kinda makes sense, given that the project is really geared towards people who are using the REPL and thus are gonna feel comfortable editing a python script."

Then as I was looking at the config, even though I understood it perfectly well and knew how to edit it perfectly well, it just seemed ... overly complicated - configurable and flexible - but complicated.

Also, FWIW, the PIP wheel (v.3.0.3) doesn't appear to have the example config.py included nor does there appear to be a way to have ptpython write the "current/default" config to a file. Which means I have to grab the template config from the repo.

Moving to an actual config file (whether in TOML, YAML, JSON, pick one...) would have the nice effect of being able to easily dump the default config on first startup so that there's something to edit.

My suggestion would be the default of writing an inline-documented config file (e.g. where the config file has comments about what the option does, valid values, etc.) It's so convenient to have the config option documentation right there and not have to look somewhere else. (And perhaps with an option to write the default config in "expert mode" or something without the commented docs - but too, removing all lines that start with a '#' would be easy enough after the fact :grin:)