Repository navigation
Redesigning the command line interface #179
Description
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
editand it takes one new option--source(and--yamlor just--format={source,yaml}) to provide the behaviour of the currentsourcecommand. - same for info about one contact: only keep the
showcommand and introduce an option--format={pretty,yaml,vcard}to provide the currentexportfunctionality (and even a new one withvcard: 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
--formatoption.
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
earboxer commentedon Jan 16, 2020
khard ls --sortcould be extended to have support for sorting by birthday, email address, phone number (or maybe just any arbitrary field?)Then, an equivalent command to
khard bdayscould bekhard 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 birthdayorkhard ls --with twitterto list only the cards that have those fields.earboxer commentedon Jan 18, 2020
Actually, it seems the only thing
khard lsis missing is the ability to specify fields.khard bdaysbecomeskhard ls -F formatted_name,birthday --sort birthdayAllowing 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 -cIf 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 2Or 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 | uniqYou 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
first_name).for nesting (address.home.region)address.homeis the same asaddress.HOME)lucc commentedon Jan 19, 2020
@earboxer the last time a though about it I sopped to persue the
--fieldsidea forlsbecause at leasetkhard phonehas a special search logic that is not sensible forls.But I still like the
--fields/-Fidea forls. Maybe it even makes sense to first design/implement a propper-Foption that has the current bhaviour oflsas 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).lucc commentedon Mar 25, 2020
Searching for contacts where some property is non empty
This is mentioned as the
--withoption in #179 (comment) and as a field modifier for-Ffields 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.
octvs commentedon Jun 19, 2023
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.