Skip to content

Redesigning the command line interface #179

Open

Description

@lucc

I have collected some thoughts and ideas about the command line interface of khard and how it could be improved. I will share them here and hope for people joining the discussion.

status quo

Currently we have 16 subcommands and some aliases. I would order them into these categories:

  • listing several contacts: ls, bdays, email, phone, file
  • displaying info about one contacts only: show, export
  • modify contents of a single contact: edit, source
  • some misc commands: merge, copy, move, rm, abooks, new, add-email

plan

I think the commands for the first three categories can be unified into three general commands with some new options (first the easy ones :)

  • modify: we could have one single command edit and it takes one new option --source (and --yaml or just --format={source,yaml}) to provide the behaviour of the current source command.
  • same for info about one contact: only keep the show command and introduce an option --format={pretty,yaml,vcard} to provide the current export functionality (and even a new one with vcard: just print the contents of the vcard on stdout)
  • also merge all listing commands into one. This is a little harder as I am not sure how we can put all these different formats into a new --format option.

All old command names could be kept as a kind of compatibility alias for some time.

format option for new ls

For compatibility the --format option could accept some special strings to mimic the exact behaviour of the old listing commands.

I light of some open pull requests about special/new listing options for some subcommands (#175, #89) we could also accept python format strings that would be interpolated with the contact objects. Then people could write their own format strings. This would also open up khard for use in custom shell scripts (which is a thing that I also would like).

One problem with format strings is that I do not know how we can implement alignment over the whole printed list. We currently do that by generating a python list with strings for each entry and then search for the longest entry in each column to adjust the amount of whitespace. With plain format strings this is not possible. One would have to implement a special string at which to inject alignment (but that introduces string parsing and escaping issues into the new format strings) or we would have to support lists of format strings so that we can insert the alignment between them. Lastly we could ignore the alignment issue for custom, user written format strings and only support it in our buildin special format name (which are meant to mimic the format of our current subcommands).

Another problem with custom format strings is that some attributes of the vcard objects are lists and we would have to decide if the format string is applied to the whole list or for each entry in turn. This corresponds to the problem in #173.

If I have enough time I will open PRs for the first to command unifications. For the listing commands I will wait for some comments first.

Activity

  1. added this to the v1.0 milestone on Jun 21, 2019
  2. added
    interfacechanges the user interface in a non trivial way
    on Aug 21, 2019
  3. earboxer commented on Jan 16, 2020

    @earboxer
    Contributor

    khard ls --sort could be extended to have support for sorting by birthday, email address, phone number (or maybe just any arbitrary field?)

    Then, an equivalent command tokhard bdays could be khard ls --sort birthday | grep '/'

    Another possible command line flag that could be useful in replacing those ls-like commands could be --with.

    You use khard ls --with birthday or khard ls --with twitter to list only the cards that have those fields.

  4. earboxer commented on Jan 18, 2020

    @earboxer
    Contributor

    Actually, it seems the only thing khard ls is missing is the ability to specify fields.

    khard bdays becomes khard ls -F formatted_name,birthday --sort birthday

    Allowing fields to be specified empowers the user to do their own processing. For example, if I wanted to count the number of people with each last name, I would just do

    khard ls -F last_name | sort | uniq -c

    If I wanted to make a list of people by what state they live in

    khard ls -p -F formatted_name,address.home.region | sort -k 2

    Or find the phone area codes used by region

    khard ls -p -F address.home.region,phone.cell | sort | sed 's/[-+ ()]//g' | sed 's/ /\t/g' | cut -f 1,2 | uniq

    You get the picture.

    The issue would be determining a good way to select fields. I suggest we do it similar to how the yaml file is spelled out, but

    • replace spaces with underscores (first_name)
    • use . for nesting (address.home.region)
    • case insensitive (address.home is the same as address.HOME)
  5. lucc commented on Jan 19, 2020

    @lucc
    OwnerAuthor

    @earboxer the last time a though about it I sopped to persue the --fields idea for ls because at leaset khard phone has a special search logic that is not sensible for ls.

    But I still like the --fields/-F idea for ls. Maybe it even makes sense to first design/implement a propper -F option that has the current bhaviour of ls as defalult and then think about which other commands it can replace. I think that is a good next step for this issue. (And I agree with your suggestion about case insensite space-replace and dots).

  6. lucc commented on Mar 25, 2020

    @lucc
    OwnerAuthor

    Searching for contacts where some property is non empty

    This is mentioned as the --with option in #179 (comment) and as a field modifier for -F fields in #246 (comment)

    I think this kind of functionallity should be represented in the custom query syntax mentioned in #131 as field: without a value meaning that the field needs to be set but the value is irelevant.

    The main reason to push this into the query language and not have an option (or a modifier on the fields) is that it is a thing to select contacts not to select data to output. These are two things I would like to seperate in the user interface.

  7. octvs commented on Jun 19, 2023

    @octvs

    I couldn't find a way to print out the value to terminal, for example Email field from a contact without the titles. which then can be copied to clipboard with piping to clipboard. I might be overlooking the fact that there might be multiple matches, which can just be fed to sed. In case it is obvious/asked before, please excuse me, if not I thought it might be relevant to this issue to be considered.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    interfacechanges the user interface in a non trivial way

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions