PortOptsCLI - Ports Collection Accessibility
Tags: a11y, freebsd, unix, sysadmin
Published: 2023-10-20 13:46:38

The [FreeBSD](https://www.freebsd.org) Operating System provides the [Ports Collection](https://www.freebsd.org/ports/) to give users and administrators a simple way to install applications.

It is possible to configure a port before the building and installation. The configuration consists of a set of lists: checklists to enable or disable an option, radiolist to select at the most one option. Some list is mandatory, at least one option has to be active.

[ports-mgmt/dialog4ports](https://www.freshports.org/ports-mgmt/dialog4ports/) and [ports-mgmt/portconfig](https://www.freshports.org/ports-mgmt/portconfig/) allow to set up a port via an interactive Text User Interface. They are implicitly used by "*make config*", example editors/vim port:

```default
# cd /usr/ports/editors/vim
# make config
```

![Window in a terminal with checklists and radiolist to set up the FreeBSD vim port](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8b9xfos0k5463r1bsa8.png)

The black and white theme can provide high-contrast accessibility for users with low vision, for portconfig >= 0.6:
```default
# env NO_COLOR="YES" make config
```
Older versions:
```default
# env PORTCONFIG_THEME="blackwhite" make config
```

![High-contrast window in a terminal with checklists and radiolist to set up the FreeBSD vim port](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3qgcnjoqhwo4rxelize4.png)

--------------------------------------------------------------

## PortOptsCLI ##

Unfortunately screen readers perform terrible with TUI, it is a well-known accessibility problem. FreeBSD provides tens of thousands of ports, port configuration is a key feature, unfortunately it is inaccessible to users with vision impairment.

[PortOptsCLI](https://gitlab.com/alfix/portoptscli) (Port Options CLI) is an utility for setting the port options via a Command Line Interface. Properly PortOptsCLI provides commands to navigate lists (checklists and/or radiolists) and set up their items interactively also suitable for a speech synthesizer. Currently it is tested with the speech synthesizer of orca <https://wiki.gnome.org/Projects/Orca>, FreeBSD provides a port and a package <https://www.freshports.org/accessibility/orca/>.

Preview <https://twitter.com/alfsiciliano/status/1694858990440648711>, video description and transcription are available in the Demo section later.

## Getting Started ##

To install the port:
```default
# cd /usr/ports/ports-mgmt/portoptscli/ && make install clean
```
or to install the package:
```default
# pkg install portoptscli
```
After the installation, add to /etc/make.conf:
```tcsh
#DIALOG4PORTS?= ${LOCALBASE}/bin/dialog4ports
DIALOG4PORTS=${LOCALBASE}/bin/portoptscli
```
Now 'make config' uses portoptscli automatically. To start to set up a port are sufficient few commands:  
**h**: specific port help if exist.
**n**: next element (header, list, option, end line).
**p**: previous element.
**r**: reprint current element.
**space**: enable or disable a checklist item, select a radiolist item.
**a**: abandon without saving.
**q**: save and quit.
All features are linked in the Documentation section later.

## Demo ##

PortOptsCLI disables ECHO and ENTER. However this demo surrounds runtime commands and comments by square brackets in a new line for ease of understanding. To note some speech synthesizer can read the typed keys depending on the current setting.

```default
# cd /usr/ports/editors/neovim
[ENTER]
# make config
[ENTER, start implicitly portoptscli]
Configuration for neovim-0.9.1 port, 1 list total 2 options.
[v]
Verbose mode on.
n: next, p: previous, r: reprint, space: select or unselect.
[n]
List 1. Generic options. Checklist with 2 options.
[n]
1 NLS: Native Language Support. Enabled.
[n]
2 PYNVIM: Enable support for plugins written in python. Disabled.
[SPACE]
option PYNVIM enabled.
[n]
End configuration. q: save and quit, a: abandon without saving, t: go to top.
[q]
Save and quit.
#
```

Another demo without commands and comments:
```default
# cd /usr/ports/editors/vim
# make config
Configuration for vim-9.0.1671 port, 3 lists total 12 options.
Verbose mode on.
n: next, p: previous, r: reprint, space: select or unselect.
List 1. Generic options. Checklist with 3 options.
1 MAKE_JOBS: Enable parallel build. Disabled.
2 NLS: Native Language Support. Enabled.
3 XTERM_SAVE: Restore xterm screen after exit. Disabled.
option XTERM_SAVE enabled.
List 2. Optional language bindings. Checklist with 6 options.
1 LUA: Lua scripting language support. Disabled.
2 PERL: Perl scripting language support. Disabled.
3 PYTHON: Python bindings or support. Enabled.
4 RUBY: Ruby bindings or support. Disabled.
5 SCHEME: MzScheme (Racket) bindings. Disabled.
6 TCL: Tcl scripting language support. Disabled.
List 3. CTAGS. RadioList with 3 options, mandatory list select at least one option.
1 CTAGS_BASE: Use system ctags. Selected.
2 CTAGS_EXUBERANT: Use exctags instead of ctags.
3 CTAGS_UNIVERSAL: Use uctags instead of ctags.
option CTAGS_UNIVERSAL selected previous CTAGS_BASE unselected.
End configuration. q: save and quit, a: abandon without saving, t: go to top.
Save and quit.
#
```

## Documentation ##

 - Manual : *$ man 1 portoptscli*, [online](2023-08-20-manual-portoptscli.html).
 - README <https://gitlab.com/alfix/portoptscli/-/raw/main/README.txt>.

## Tips ##

Verbose mode can be set by the PORTOPTSCLI_VERBOSE="YES" environment variable.

The *c* key prints the short commands list described in the Getting Started:
```default
# make config
Configuration for neovim-0.9.1 port, 1 list total 2 options.
[c]
Short commands list.
h: specific port help if exist.
i: port and lists info.
n: next element.
p: previouse element.
r: reprint element.
space: select or unselect an option.
a: abandon without saving.
q: save and quit.
[a]

===> Options unchanged
#
```

Some port has a specific help file, if it exists PortOptsCLI informs at startup/top, h key to print it:
```default
# cd /usr/ports/devel/pcre/
# make config
Configuration for pcre-8.45_3 port, 2 lists total 6 options.
The port has a help file, h: to print.
[h]
Help file /usr/ports/devel/pcre/pkg-help.
Using the heap rather than the stack for recursion (i.e., turning the
STACK_RECURSION knob off) is slower but less prone to segfaults from
stack exhaustion when matching certain patterns.
End help file.
[a]

===> Options unchanged
```

## Suggestions, bug report, new ideas ##

- My [contacts](https://alfonsosiciliano.gitlab.io/about.html) for private discussions.
- FreeBSD [Accessibility](https://lists.freebsd.org/subscription/freebsd-accessibility) mailing list to share and to track discussions in a public place.

--------------------------------------------------------------

## Extras ##

FreeBSD also allows you to configure a port using environment variables or configuration files, both ways are described in the [port(7)](https://man.freebsd.org/ports/7) manual.

Resources and links for further information:

 - Ports intro, [online](https://www.freebsd.org/ports/).
 - Manual: *$ man 7 ports*, [online](https://man.freebsd.org/ports/7).
 - */usr/ports/README*, [online](https://cgit.freebsd.org/ports/plain/README).
 - FreeBSD Handbook "*4.5. Using the Ports Collection*",    [online](https://docs.freebsd.org/en/books/handbook/ports/#ports-using).