cmdr
Artifact Content
Not logged in

Artifact 53147a6b82079c96baa73d9ba8da32bb1076938a:


'\"
'\" Generated from file 'cmdr_dev_completion\&.man' by tcllib/doctools with format 'nroff'
'\" Copyright (c) 2013-2016 Andreas Kupries
'\" Copyright (c) 2013-2016 Documentation, Andreas Kupries
'\"
.TH "cmdr_dev~completion" n 1\&.2 doc "Cmdr, a framework for command line parsing and dispatch"
.\" The -*- nroff -*- definitions below are for supplemental macros used
.\" in Tcl/Tk manual entries.
.\"
.\" .AP type name in/out ?indent?
.\"	Start paragraph describing an argument to a library procedure.
.\"	type is type of argument (int, etc.), in/out is either "in", "out",
.\"	or "in/out" to describe whether procedure reads or modifies arg,
.\"	and indent is equivalent to second arg of .IP (shouldn't ever be
.\"	needed;  use .AS below instead)
.\"
.\" .AS ?type? ?name?
.\"	Give maximum sizes of arguments for setting tab stops.  Type and
.\"	name are examples of largest possible arguments that will be passed
.\"	to .AP later.  If args are omitted, default tab stops are used.
.\"
.\" .BS
.\"	Start box enclosure.  From here until next .BE, everything will be
.\"	enclosed in one large box.
.\"
.\" .BE
.\"	End of box enclosure.
.\"
.\" .CS
.\"	Begin code excerpt.
.\"
.\" .CE
.\"	End code excerpt.
.\"
.\" .VS ?version? ?br?
.\"	Begin vertical sidebar, for use in marking newly-changed parts
.\"	of man pages.  The first argument is ignored and used for recording
.\"	the version when the .VS was added, so that the sidebars can be
.\"	found and removed when they reach a certain age.  If another argument
.\"	is present, then a line break is forced before starting the sidebar.
.\"
.\" .VE
.\"	End of vertical sidebar.
.\"
.\" .DS
.\"	Begin an indented unfilled display.
.\"
.\" .DE
.\"	End of indented unfilled display.
.\"
.\" .SO ?manpage?
.\"	Start of list of standard options for a Tk widget. The manpage
.\"	argument defines where to look up the standard options; if
.\"	omitted, defaults to "options". The options follow on successive
.\"	lines, in three columns separated by tabs.
.\"
.\" .SE
.\"	End of list of standard options for a Tk widget.
.\"
.\" .OP cmdName dbName dbClass
.\"	Start of description of a specific option.  cmdName gives the
.\"	option's name as specified in the class command, dbName gives
.\"	the option's name in the option database, and dbClass gives
.\"	the option's class in the option database.
.\"
.\" .UL arg1 arg2
.\"	Print arg1 underlined, then print arg2 normally.
.\"
.\" .QW arg1 ?arg2?
.\"	Print arg1 in quotes, then arg2 normally (for trailing punctuation).
.\"
.\" .PQ arg1 ?arg2?
.\"	Print an open parenthesis, arg1 in quotes, then arg2 normally
.\"	(for trailing punctuation) and then a closing parenthesis.
.\"
.\"	# Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
.if t .wh -1.3i ^B
.nr ^l \n(.l
.ad b
.\"	# Start an argument description
.de AP
.ie !"\\$4"" .TP \\$4
.el \{\
.   ie !"\\$2"" .TP \\n()Cu
.   el          .TP 15
.\}
.ta \\n()Au \\n()Bu
.ie !"\\$3"" \{\
\&\\$1 \\fI\\$2\\fP (\\$3)
.\".b
.\}
.el \{\
.br
.ie !"\\$2"" \{\
\&\\$1	\\fI\\$2\\fP
.\}
.el \{\
\&\\fI\\$1\\fP
.\}
.\}
..
.\"	# define tabbing values for .AP
.de AS
.nr )A 10n
.if !"\\$1"" .nr )A \\w'\\$1'u+3n
.nr )B \\n()Au+15n
.\"
.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
.nr )C \\n()Bu+\\w'(in/out)'u+2n
..
.AS Tcl_Interp Tcl_CreateInterp in/out
.\"	# BS - start boxed text
.\"	# ^y = starting y location
.\"	# ^b = 1
.de BS
.br
.mk ^y
.nr ^b 1u
.if n .nf
.if n .ti 0
.if n \l'\\n(.lu\(ul'
.if n .fi
..
.\"	# BE - end boxed text (draw box now)
.de BE
.nf
.ti 0
.mk ^t
.ie n \l'\\n(^lu\(ul'
.el \{\
.\"	Draw four-sided box normally, but don't draw top of
.\"	box if the box started on an earlier page.
.ie !\\n(^b-1 \{\
\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.el \}\
\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.\}
.fi
.br
.nr ^b 0
..
.\"	# VS - start vertical sidebar
.\"	# ^Y = starting y location
.\"	# ^v = 1 (for troff;  for nroff this doesn't matter)
.de VS
.if !"\\$2"" .br
.mk ^Y
.ie n 'mc \s12\(br\s0
.el .nr ^v 1u
..
.\"	# VE - end of vertical sidebar
.de VE
.ie n 'mc
.el \{\
.ev 2
.nf
.ti 0
.mk ^t
\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
.sp -1
.fi
.ev
.\}
.nr ^v 0
..
.\"	# Special macro to handle page bottom:  finish off current
.\"	# box/sidebar if in box/sidebar mode, then invoked standard
.\"	# page bottom macro.
.de ^B
.ev 2
'ti 0
'nf
.mk ^t
.if \\n(^b \{\
.\"	Draw three-sided box if this is the box's first page,
.\"	draw two sides but no top otherwise.
.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.\}
.if \\n(^v \{\
.nr ^x \\n(^tu+1v-\\n(^Yu
\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
.\}
.bp
'fi
.ev
.if \\n(^b \{\
.mk ^y
.nr ^b 2
.\}
.if \\n(^v \{\
.mk ^Y
.\}
..
.\"	# DS - begin display
.de DS
.RS
.nf
.sp
..
.\"	# DE - end display
.de DE
.fi
.RE
.sp
..
.\"	# SO - start of list of standard options
.de SO
'ie '\\$1'' .ds So \\fBoptions\\fR
'el .ds So \\fB\\$1\\fR
.SH "STANDARD OPTIONS"
.LP
.nf
.ta 5.5c 11c
.ft B
..
.\"	# SE - end of list of standard options
.de SE
.fi
.ft R
.LP
See the \\*(So manual entry for details on the standard options.
..
.\"	# OP - start of full description for a single option
.de OP
.LP
.nf
.ta 4c
Command-Line Name:	\\fB\\$1\\fR
Database Name:	\\fB\\$2\\fR
Database Class:	\\fB\\$3\\fR
.fi
.IP
..
.\"	# CS - begin code excerpt
.de CS
.RS
.nf
.ta .25i .5i .75i 1i
..
.\"	# CE - end code excerpt
.de CE
.fi
.RE
..
.\"	# UL - underline word
.de UL
\\$1\l'|0\(ul'\\$2
..
.\"	# QW - apply quotation marks to word
.de QW
.ie '\\*(lq'"' ``\\$1''\\$2
.\"" fix emacs highlighting
.el \\*(lq\\$1\\*(rq\\$2
..
.\"	# PQ - apply parens and quotation marks to word
.de PQ
.ie '\\*(lq'"' (``\\$1''\\$2)\\$3
.\"" fix emacs highlighting
.el (\\*(lq\\$1\\*(rq\\$2)\\$3
..
.\"	# QR - quoted range
.de QR
.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3
.\"" fix emacs highlighting
.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3
..
.\"	# MT - "empty" string
.de MT
.QW ""
..
.BS
.SH NAME
cmdr_dev~completion \- Cmdr - Internals of command line completion
.SH SYNOPSIS
package require \fBcmdr \fR
.sp
.BE
.SH DESCRIPTION
.PP
Welcome to the Cmdr project, written by Andreas Kupries\&.
.PP
For availability please read \fICmdr - How To Get The Sources\fR\&.
.PP
This internal document provides an overview on how the framework
performs command-line completion in both the main and mini shells,
referencing all the relevant methods and describing the data
structures in use\&.
.PP
For more information about other internals of the framework
please read \fICmdr - The Developer's Guide\fR\&.
.SH "CODE OVERVIEW"
The methods relevant to command-line completion can be found in four
packages/classes, namely:
.TP
\fBcmdr::actor\fR
.RS
.TP
\fBparse-line\fR
Takes a command-line and returns an initial parse structure as
described in section \fBParse State\fR
.TP
\fBcompletions\fR
.TP
\fBmatch\fR
.RE
.TP
\fBcmdr::config\fR
.RS
.TP
\fBcomplete\fR
Hook method, entrypoint for the mini-shell\&.
Takes the buffer to complete and returns the list of completions,
which may be empty\&.
Uses the workhorse method below and the \fBcmdr::actor\fR
methods\&.
.TP
\fBcomplete-repl\fR
Main work method taking a parse structure and returning the list
of completions\&. More details about it (and the mini-shell) can be
found in section \fBMini Shell Operation\fR\&.
.TP
\fBcomplete-words\fR
Main work method for completion from the main shell, invoked by
the \fBcmdr::private\fR instance having to complete words\&.
.RE
.TP
\fBcmdr::officer\fR
.RS
.TP
\fBcomplete\fR
Hook method, entrypoint for the main shell\&.
Takes the buffer to complete and returns the list of completions,
which may be empty\&.
Uses the workhorse method below and the \fBcmdr::actor\fR
methods\&.
.TP
\fBcomplete-words\fR
Main work method taking a parse structure and returning the list
of completions\&. More details about it (and the main shell) can be
found in section \fBMain Shell Operation\fR\&.
.sp
Can recurse to the same method of other officers, and
private instances\&.
.RE
.TP
\fBcmdr::parameter\fR
.RS
.TP
\fBcomplete-words\fR
Main work method when reaching a parameter\&.
Simply delegates the work to the method \fBcomplete\fR of the
validation type associated with the parameter\&.
.RE
.TP
\fBcmdr::private\fR
.RS
.TP
\fBcomplete-words\fR
Main work method when reaching a private while recursing through
the command hierarchy from officers\&.
Delegates to the \fBcmdr::config\fR method of the same name\&.
.RE
.PP
.SH "PARSE STATE"
The state structure used by all methods relevant to command line
completion is a dictionary containing the six keys listed below\&.
The only generator for this structure is method \fBparse-line\fR of
the base-class \fBcmdr::actor\fR\&. All others parts of the system
then only read and manipulate it\&.
.TP
\fBok\fR
A boolean flag\&. Indicates if the \fBline\fR parsed sucessfully into
words (\fBtrue\fR), or not (\fBfalse\fR, syntax error)\&.
.sp
The framework expects basic shell syntax with space-separated
words using single- and double-quotes for words containing whitespace
themselves\&. Note that complex syntax like variable- and
command-substitutions are not allowed\&.
.TP
\fBline\fR
A copy of the unparsed command line\&.
.TP
\fBwords\fR
The command \fBline\fR parsed into the bare words\&. The data is not
valid if \fBok\fR indicates a parsing error\&. This is not a list of
strings, but actually a list of tokens\&.
.sp
Each token is a list of four elements containing, in the order
below:
.RS
.IP [1]
Type of the token (implicitly specifies found quoting)\&.
.IP [2]
Start index of token in \fBline\fR including quoting\&.
.IP [3]
End index of token in \fBline\fR, including quoting\&.
.IP [4]
The string value of the token, with escapes fully resolved\&.
I\&.e\&. the actual word\&.
.RE
.sp
Note: If \fBline\fR ended in trailing whitespace the last
element of this list will be an empty string representing the word
started by the user, yet still empty\&.
.TP
\fBnwords\fR
The number of element in \fBwords\fR\&. The data is not valid if
\fBok\fR indicates a parsing error\&.
.TP
\fBat\fR
The index of the \fIcurrent word\fR in \fBwords\fR currently
considered by the completion code\&. Initially \fB0\fR this advances
as the completion code works through the prefix to determine the
context for the completion of the last word\&.
.TP
\fBdoexit\fR
A boolean flag\&. Indicates if the pseudo-command \fB\&.exit\fR is active
(\fBtrue\fR), or not\&. Initially \fBtrue\fR\&.
.PP
.SH "MAIN SHELL OPERATION"
.SS OVERVIEW
The \fImain shell\fR is fully implemented within the package
\fBcmdr::officer\fR, while its command-line completion also
reaches into the packages \fBcmdr::private\fR,
\fBcmdr::config\fR, and \fBcmdr::parameter\fR\&.
The purpose of this shell is interactive access to the commands of an
officer\&. Which implies, for the toplevel officer, access to the entire
command hierarchy\&.
.PP
To this end this shell accepts the names of all subordinate
commands known to the officer as commands\&.
.PP
It may additional accept a hard-wired command \fB\&.exit\fR,
depending on the parse state (see flag \fBdoexit\fR)\&.
.SS "SEQUENCING AND RULES"
.PP
IMAGE: main-shell
.PP
This rest of this section is a textual description of the UML
sequence diagram shown above\&.
.PP
Note that the state structure used by this code and referenced
in the text is explained in section \fBParse State\fR\&.
.IP [1]
The main shell's core read-eval-print-loop calls on the
instance method \fBcomplete\fR for command-line completion,
providing the text of the buffer to complete at the end)\&.
.IP [2]
The method \fBcmdr::actor\fR::\fBparse-line\fR is called
on first, to get a parse of the buffer\&. This parse is then delegated
to the instance method \fBcomplete-words\fR to perform the bulk of
the work\&.
.sp
Note: The officer instance has access to \fBparse-line\fR
because it is a derived class of \fBcmdr::actor\fR\&.
.IP [3]
The implementation of method \fBcomplete-words\fR applies
the rules below:
.RS
.IP [1]
If the buffer was not properly parsed (i\&.e\&. the state indicates
a syntax error), the list of completions is empty\&.
.IP [2]
When the buffer is empty all commands are possible completions,
as are all the commands of the default subordinate, if any was
specified\&.
.IP [3]
If the \fIcurrent word\fR (as per \fBat\fR) is the last
word (per \fBnwords\fR) on the command line then completion is done
using the set of commands known to the officer and its default
subordinate, if any\&.
.IP [4]
For a \fIcurrent word\fR which is not the last, i\&.e\&. at the
beginning or in the middle of the command line instead, then this word
is the name of the subordinate object responsible for handling the
remaining words\&.
.sp
No completion is done however if the current word does not
yield a subordinate to delegate to (i\&.e\&. unknown or ambigous)\&. If a
default command is known this case will delegate to this subordinate,
as a last attempt\&.
.sp
When a subordinate was found the system advances the current
word, resets the \fBdoexit\fR flag, and lastly invokes the method
\fBcomplete-words\fR of the sub-ordinate\&.
.IP [5]
When the subordinate is again an \fIofficer\fR, these rules
here apply again\&.
.IP [6]
A \fIprivate\fR however will delegate to the embedded
\fBcmdr::config\fR instance, again using the method
\fBcomplete-words\fR\&.
.IP [7]
This method processes the remaining words similar to how the
command line is parsed at runtime to match words to parameters, to
know at the end which (set of) parameter(s) governs the last word\&.
.sp
For \fIoptions\fR the last word may be partial name of a flag,
or it may be the partial argument to an option\&.
In case of the first the set of completions is the set of all flags
with the word as its prefix\&.
In case of the second the completion delegates to the parameter
governing the flag, if there is any, which in turn delegates to its
associated validation type\&.
.sp
For \fIinputs\fR the system essentially steps through a
non-deterministic finite automaton to find all the parameters which
may govern the current word\&. Completion is done as the union of the
completion done by the individual parameters\&.
.sp
Note that the automaton and its results can be precomputed,
this happens in the internal method \fBCompletionGraph\fR\&.
.RE
.PP
.SH "MINI SHELL OPERATION"
.SS OVERVIEW
The \fImini shell\fR and its command-line completion is fully
implemented within the package \fBcmdr::config\fR\&.
The purpose of this shell is the interactive entry of the parameters
for a \fIprivate\fR\&.
.PP
To this end this shell accepts the \fIsystem\fR names of all
parameters held by the config instance as commands, plus five
hard-wired commands to control exit conditions and access to help\&.
.PP
The parameter commands all take single value as their argument,
the string value to set\&.
The sole exception to this are \fIpresence options\fR which do not
take any argument\&.
.PP
Similarly none of the hardwired commands take an
argument\&. Their names all start with a \fB\&.\fR\&. They are, in
alphabetical order, \fB\&.cancel\fR, \fB\&.exit\fR, \fB\&.help\fR \fB\&.ok\fR, and \fB\&.run\fR\&.
.SS "SEQUENCING AND RULES"
.PP
IMAGE: mini-shell
.PP
This rest of this section is a textual description of the UML
sequence diagram shown above\&.
.PP
Note that the state structure used by this code and referenced
in the text is explained in section \fBParse State\fR\&.
.IP [1]
The mini shell's core read-eval-print-loop calls on the
instance method \fBcomplete\fR for command-line completion,
providing the text of the buffer to complete at the end)\&.
.IP [2]
The method \fBcmdr::actor\fR::\fBparse-line\fR is called
on first, to get a parse of the buffer\&. This parse is then delegated
to the instance method \fBcomplete-repl\fR to perform the bulk of
the work\&.
.sp
Note: The config instance has access to \fBparse-line\fR
through its internal \fBcontext\fR command, which is an alias of the
\fBcmdr::private\fR instance the configuration belongs to\&. This
class is derived from \fBcmdr::actor\fR\&.
.IP [3]
The implementation of method \fBcomplete-repl\fR applies the
rules below:
.RS
.IP [1]
If the buffer was not properly parsed (i\&.e\&. the state indicates
a syntax error), the list of completions is empty\&.
.IP [2]
When the buffer is empty all commands are possible completions\&.
.IP [3]
When the buffer contains more than three words the list of
completions is empty, as all valid mini-shell commands consist of at
most two words\&.
.IP [4]
A buffer containing a single word contain a partial command
name and the list of completions is the set of commands having this
word as prefix\&.
.IP [5]
A buffer containing two words contains a command name and a
partial argument\&. Completion is delegated to the parameter (method
\fBcmdr::parameter\fR::\fBcomplete-words\fR) indicated by the
command name, and through it to the associated validation type\&.
.sp
No completion is done however if the first word does not yield
a parameter to delegate to (i\&.e\&. unknown or ambigous), or if it is a
presence option, which does not take an argument\&.
.sp
The hardwired commands fall here implicitly under unknown
parameter\&.
.RE
.PP
.SH "BUGS, IDEAS, FEEDBACK"
Both the package(s) and this documentation will undoubtedly contain
bugs and other problems\&.
Please report such at
\fICmdr Tickets\fR [https:/core\&.tcl\&.tk/akupries/cmdr]\&.
.PP
Please also report any ideas you may have for enhancements of
either package(s) and/or documentation\&.
.SH KEYWORDS
arguments, command hierarchy, command line completion, command line handling, command tree, editing command line, help for command line, hierarchy of commands, interactive command shell, optional arguments, options, parameters, processing command line, tree of commands
.SH COPYRIGHT
.nf
Copyright (c) 2013-2016 Andreas Kupries
Copyright (c) 2013-2016 Documentation, Andreas Kupries

.fi