Update docs

This commit is contained in:
Janne Valkealahti
2023-10-07 08:09:51 +01:00
parent 2e95fccbd5
commit 9a5f189783
17 changed files with 30 additions and 24 deletions

View File

@@ -0,0 +1,43 @@
[[command-catalog]]
= Command Catalog
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
The `CommandCatalog` interface defines how command registrations exist in
a shell application. It is possible to dynamically register and de-register
commands, which gives flexibility for use cases where possible commands
come and go, depending on a shell's state. Consider the following example:
[source, java, indent=0]
----
include::{snippets}/CommandCatalogSnippets.java[tag=snippet1]
----
[[command-resolver]]
== Command Resolver
You can implement the `CommandResolver` interface and define a bean to dynamically
resolve mappings from a command's name to its `CommandRegistration` instances. Consider
the following example:
[source, java, indent=0]
----
include::{snippets}/CommandCatalogSnippets.java[tag=snippet2]
----
IMPORTANT: A current limitation of a `CommandResolver` is that it is used every time commands are resolved.
Thus, we advise not using it if a command resolution call takes a long time, as it would
make the shell feel sluggish.
[[command-catalog-customizer]]
== Command Catalog Customizer
You can use the `CommandCatalogCustomizer` interface to customize a `CommandCatalog`.
Its main use is to modify a catalog. Also, within `spring-shell` auto-configuration, this
interface is used to register existing `CommandRegistration` beans into a catalog.
Consider the following example:
[source, java, indent=0]
----
include::{snippets}/CommandCatalogSnippets.java[tag=snippet3]
----
You can create a `CommandCatalogCustomizer` as a bean, and Spring Shell handles the rest.

View File

@@ -0,0 +1,21 @@
[[command-context]]
= Command Context
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
The `CommandContext` interface gives access to a currently running
context. You can use it to get access to options:
[source, java, indent=0]
----
include::{snippets}/CommandContextSnippets.java[tag=snippet1]
----
If you need to print something into a shell, you can get a `Terminal`
and use its writer to print something:
[source, java, indent=0]
----
include::{snippets}/CommandContextSnippets.java[tag=snippet2]
----

View File

@@ -0,0 +1,8 @@
[[command-execution]]
= Command Execution
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
When command parsing has done its job and command registration has been resolved, command execution
does the hard work of running the code.

View File

@@ -0,0 +1,14 @@
[appendix]
[#appendix-tech-intro]
= Techical Introduction
:page-section-summary-toc: 1
This appendix contains information for developers and others who would like to know more about how Spring Shell
works internally and what its design decisions are.

View File

@@ -0,0 +1,6 @@
[[command-parser]]
= Command Parser
:page-section-summary-toc: 1
Before a command can be executed, we need to parse the command and whatever options the user may have provided. Parsing
comes between command registration and command execution.

View File

@@ -0,0 +1,99 @@
[#appendix-tech-intro-registration]
= Command Registration
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
Defining a command registration is a first step to introducing the structure of a command and its options
and parameters. This is loosely decoupled from what happens later, such as parsing command-line input and running
actual target code. Essentially, it is the definition of a command API that is shown to a user.
[[commands]]
== Commands
A command in a `spring-shell` structure is defined as an array of commands. This yields a
structure similar to the following example:
[source, bash]
----
command1 sub1
command2 sub1 subsub1
command2 sub2 subsub1
command2 sub2 subsub2
----
NOTE: We do not currently support mapping commands to an explicit parent if sub-commands are defined.
For example, `command1 sub1` and `command1 sub1 subsub1` cannot both be registered.
[[interaction-mode]]
== Interaction Mode
Spring Shell has been designed to work on two modes: interactive (which essentially
is a `REPL` where you have an active shell instance throughout a series of commands) and
non-interactive (where commands are executed one by one from a command line).
Differentation between these modes is mostly around limitations about what can be done
in each mode. For example, it would not be feasible to show what was a previous stacktrace
of a command if the shell is no longer active. Generally, whether the shell is still active
dictates the available information.
Also, being on an active `REPL` session may provide more information about what the user has been
doing within an active session.
[[options]]
== Options
Options can be defined as long and short, where the prefixing is `--` and `-`, respectively.
The following examples show long and short options:
[source, java, indent=0]
----
include::{snippets}/CommandRegistrationSnippets.java[tag=snippet1]
----
[source, java, indent=0]
----
include::{snippets}/CommandRegistrationSnippets.java[tag=snippet2]
----
[[target]]
== Target
The target defines the execution target of a command. It can be a method in a POJO,
a `Consumer`, or a `Function`.
[[method]]
=== Method
Using a `Method` in an existing POJO is one way to define a target.
Consider the following class:
[source, java, indent=0]
----
include::{snippets}/CommandTargetSnippets.java[tag=snippet11]
----
Given the existing class shown in the preceding listing, you can then register its method:
[source, java, indent=0]
----
include::{snippets}/CommandTargetSnippets.java[tag=snippet12]
----
[[function]]
=== Function
Using a `Function` as a target gives a lot of flexibility to handle what
happens in a command execution, because you can handle many things manually by using
a `CommandContext` given to a `Function`. The return type from a `Function` is
then what gets printed into the shell as a result. Consider the following example:
[source, java, indent=0]
----
include::{snippets}/CommandTargetSnippets.java[tag=snippet2]
----
[[consumer]]
=== Consumer
Using a `Consumer` is basically the same as using a `Function`, with the difference being
that there is no return type. If you need to print something into a shell,
you can get a reference to a `Terminal` from a context and print something
through it. Consider the following example:
[source, java, indent=0]
----
include::{snippets}/CommandTargetSnippets.java[tag=snippet3]
----

View File

@@ -0,0 +1,65 @@
[#appendix-tech-intro-searchalgorithm]
= Search Algorithms
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
`SearchMatch` is an interface to match _text_ with a _pattern_. Match
results are in a returned value `SearchMatchResult`. Match result
contains info about match positions and overall score of a match.
https://github.com/junegunn/fzf[fzf].
[[implementations]]
== Implementations
*FuzzyMatchV2Search*
Port of _fzf FuzzyMatchV2Search_ algorithm. Does a fast fuzzy search and is good
quickly finding paths.
*ExactMatchNaive*
Port of _fzf ExactMatchNaive_ algorithm. Simple exact match works more accurately
if you know what to search.
[[searchmatch]]
== SearchMatch
Algorithms and default syntax are hidden inside package protected classes
as we don't want to fully open these until we know API's are good to go
for longer support. You need to construct `SearchMatch` via its
build-in builder.
[source, java, indent=0]
----
include::{snippets}/SearchAlgorithmsSnippets.java[tag=builder]
----
It's possible to configure _case sensitivity_, on what _direction_ search
happens or if text should be _normilized_ before search happens. Normalization
is handy when different languages have sligh variation for same type
of characters.
Search algorithm is selected based on a search syntax shown in
below table.
.Search syntax
|===
|Token |Match type |Description
|`hell`
|fuzzy-match
|Items that match `hello`
|`'stuff`
|exact-match
|Items that include `stuff`
|===
[[examples]]
== Examples
[source, java, indent=0]
----
include::{snippets}/SearchAlgorithmsSnippets.java[tag=simple]
----

View File

@@ -0,0 +1,55 @@
[#appendix-tech-intro-theming]
= Theming
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
Styling in a theming is provided by a use of a _AttributedString_ from `JLine`.
Unfortunately styling in `JLine` is mostly undocumented but we try to go through
some of its features here.
In `JLine` a style spec is a string having a special format. Spec can be given
multiple times if separated by a comma. A spec will either define a color for
foreground, background or its mode. Special format `<spec>:=<spec>` allows to
define a default within latter spec if former for some reason is invalid.
If spec contains a colon its former part indicates either foreground or background
and possible values are `foreground`, `fg`, `f`, `background`, `bg`, `b`, `foreground-rgb`,
`fg-rgb`, `f-rgb`, `background-rgb`, `bg-rgb` or `b-rgb`. Without rbg a color value
is name from an allowable colors `black`, `red`, `green`, `yellow`, `blue`, `magenta`,
`cyan` or `white`. Colors have their short formats `k`, `r`, `g`, `y`, `b`, `m`, `c` and `w`
respectively. If color is prefixed with either `!` or `bright-`, bright mode is automatically
applied. Prefixing with `~` will resolve from JLine internal bsd color table.
If rgb format is expected and prefixed with either `x` or `#` a normal
hex format is used.
[source, text]
----
fg-red
fg-r
fg-rgb:red
fg-rgb:xff3333
fg-rgb:#ff3333
----
If spec contains special names `default`, `bold`, `faint`, `italic`, `underline`, `blink`,
`inverse`, `inverse-neg`, `inverseneg`, `conceal`, `crossed-out`, `crossedout` or `hidden`
a style is changed accordingly with an existing color.
[source, text]
----
bold
bold,fg:red
----
If spec is a number or numbers separated with semicolon, format is a plain part of an ansi
ascii codes.
[source, text]
----
31
31;1
----
NOTE: JLine special mapping format which would resolve spec starting with dot can't be
used as we don't yet map those into Spring Shell styling names.