Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

kdb-complete minor improvements #1310

Merged
merged 7 commits into from
Feb 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions doc/help/kdb-complete.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@ kdb-complete(1) -- Show suggestions how to complete a given path

## SYNOPSIS

`kdb complete <path>`
`kdb complete [path]`

Where `path` is the path for which the user would like to receive completion suggestion.
If `path` is not specified, it will show every possible completion. Its synonymous
to calling `kdb complete ""`.

## DESCRIPTION

Show suggestions how the current name could be completed.
Suggestions will include existing key names, path segments of existing key names and mountpoints.
Additionally, the output will indicate wheter the given path is a node or a leaf in the hierarchy of keys.
Suggestions will include existing key names, path segments of existing key names,
namespaces and mountpoints.
Additionally, the output will indicate whether the given path is a node or a leaf
in the hierarchy of keys, nodes end with '/' as opposed to leaves.
It will also work for cascading keys, and will additionally display a cascading
key's namespace in the output to indicate from which namespace this suggestion
originates from.

## OPTIONS

Expand All @@ -22,18 +29,29 @@ Additionally, the output will indicate wheter the given path is a node or a leaf
- `-p`, `--profile`=<profile>:
Use a different kdb profile.
- `-m`, `--min-depth`=<min-depth>:
Specify the minimum depth of completion suggestions (0 by default), exclusive.
Specify the minimum depth of completion suggestions (0 by default), exclusive
and relative to the name to complete.
- `-M`, `--max-depth`=<max-depth>:
Specify the maximum depth of completion suggestions (unlimited by default, 1 to show only the next level), inclusive.
Specify the maximum depth of completion suggestions (unlimited by default, 1
to show only the next level), inclusive and relative to the name to complete.
- `-v`, `--verbose`:
Explain what is happening.
Give a more detailed output, showing the number of child nodes and the depth level.
- `-0`, `--null`:
Use binary 0 termination.
- `-d`, `--debug`:
Give debug information.

## EXAMPLES

To show all possible completions:
`kdb complete`

To show namespace suggestions:
`kdb complete --max-depth=1`

To show all possible completions for a cascading key:
`kdb complete /te`

To show all possible completions for `user/te`:
`kdb complete user/te`

Expand All @@ -42,5 +60,6 @@ To show all possible completions for the next level for `user/te`:

## SEE ALSO

- If you would only like to see existing keys under a given path, consider using the [kdb-ls(1)](kdb-ls.md) command.
- If you would only like to see existing keys under a given path, consider using
the [kdb-ls(1)](kdb-ls.md) command.
- [elektra-key-names(7)](elektra-key-names.md) for an explanation of key names.
69 changes: 46 additions & 23 deletions src/tools/kdb/cmdline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,17 @@ Cmdline::Cmdline (int argc, char ** argv, Command * command)
{
option o = { "min-depth", optional_argument, nullptr, 'm' };
long_options.push_back (o);
helpText += "-m --min-depth Specify the minimum depth of completion suggestions (0 by default), exclusive.\n";
helpText +=
"-m --min-depth Specify the minimum depth of completion suggestions (0 by default), inclusive "
"and relative to the name to complete.\n";
}
if (acceptedOptions.find ('M') != string::npos)
{
option o = { "max-depth", optional_argument, nullptr, 'M' };
long_options.push_back (o);
helpText +=
"-M --max-depth Specify the maximum depth of completion suggestions (unlimited by default, 1 to show "
"only the next level), inclusive.\n";
"only the next level), exclusive and relative to the name to complete.\n";
}
if (acceptedOptions.find ('n') != string::npos)
{
Expand Down Expand Up @@ -520,7 +522,40 @@ kdb::Key Cmdline::createKey (int pos) const
throw invalid_argument ("<empty string> is not a valid keyname. Please enter a valid one.");
}

kdb::Key root (name, KEY_END);

if (name[0] == '+')
{
kdb::Key bookmark = resolveBookmark (name);
if (!bookmark.isValid ())
{
throw invalid_argument ("cannot find bookmark " + bookmark.getFullName ());
}
root = bookmark;
}

if (!root.isValid ())
{
throw invalid_argument (name + " is not a valid keyname" + "\n\n" +
"For absolute keys (starting without '/'), please note that only one of the predefined namespaces "
"can be used (see 'man elektra-namespaces').\n" +
"Please also ensure that the path is separated by a '/'.\n" +
"An example for a valid absolute key is user/a/key, and for a valid cascading key /a/key.");
}

return root;
}

/**
* @brief resolve the bookmark with the given name
*
* @param bookmark the name of the bookmark to resolve
*
* @return a key to the resolved bookmark, or an invalid key if no bookmark with the given name exists
*/
kdb::Key Cmdline::resolveBookmark (std::string name) const
{
if (!name.empty () && name[0] == '+')
{
size_t found = name.find ('/');
std::string bookmark;
Expand All @@ -536,30 +571,18 @@ kdb::Key Cmdline::createKey (int pos) const
}
auto realKeyIt = bookmarks.find (bookmark);
std::string realKey;
if (realKeyIt == bookmarks.end ())
{
throw invalid_argument ("cannot find bookmark " + bookmark);
}
realKey = realKeyIt->second;
name = realKey + "/" + restKey;
if (verbose)
if (realKeyIt != bookmarks.end ())
{
std::cout << "using bookmark " << bookmark << " which is: " << realKey << "-" << restKey << std::endl;
realKey = realKeyIt->second;
name = realKey + "/" + restKey;
if (verbose)
{
std::cout << "using bookmark " << bookmark << " which is: " << realKey << "-" << restKey << std::endl;
}
return kdb::Key (name, KEY_END);
}
}

kdb::Key root (name, KEY_END);

if (!root.isValid ())
{
throw invalid_argument (name + " is not a valid keyname" + "\n\n" +
"For absolute keys (starting without '/'), please note that only one of the predefined namespaces "
"can be used (see 'man elektra-namespaces').\n" +
"Please also ensure that the path is separated by a '/'.\n" +
"An example for a valid absolute key is user/a/key, and for a valid cascading key /a/key.");
}

return root;
return kdb::Key ();
}

std::ostream & operator<< (std::ostream & os, Cmdline & cl)
Expand Down
1 change: 1 addition & 0 deletions src/tools/kdb/cmdline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class Cmdline
std::string profile;

kdb::Key createKey (int pos) const;
kdb::Key resolveBookmark (std::string name) const;

kdb::KeySet getPluginsConfig (std::string basepath = "user/") const;

Expand Down
Loading