Slide 1

Slide 1 text

CL EYE-CATCHING CL EYE-CATCHING USER INTERFACES USER INTERFACES GopherCon August 29, 2018 https://bit.ly/cli-ui

Slide 2

Slide 2 text

James Bowes Technical Lead @ Worked on many CLI tools no-one uses any more (up2date, yum) Loves Cats Loves Terminals ABOUT ME ABOUT ME  @jrbowes Manifold

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

YOU WILL LEARN HOW TO YOU WILL LEARN HOW TO make progress bars and spinners decorate text draw anywhere on the terminal collect input do fancy things with mice and images ...safely, for any operating system

Slide 6

Slide 6 text

YOU WILL LEARN HOW TO YOU WILL LEARN HOW TO make progress bars and spinners decorate text draw anywhere on the terminal collect input do fancy things with mice and images ...safely, for any operating system*

Slide 7

Slide 7 text

* Recent versions of Mac OS, Linux, and Windows

Slide 8

Slide 8 text

* Recent versions of Mac OS, Linux, and Windows**

Slide 9

Slide 9 text

* Recent versions of Mac OS, Linux, and Windows** ** For common terminals

Slide 10

Slide 10 text

NOTABLY ABSENT NOTABLY ABSENT Command line argument parsing Environment variables

Slide 11

Slide 11 text

NOT JUST FOR GO NOT JUST FOR GO Share these system calls and escape sequences with your non-gopher friends.

Slide 12

Slide 12 text

NOT JUST FOR GO NOT JUST FOR GO Share these system calls and escape sequences with your non-gopher friends. Use a package for real code.

Slide 13

Slide 13 text

GO IS AWESOME FOR CLIS GO IS AWESOME FOR CLIS Great support for Windows, Mac OS, Linux Easy cross compilation with GOOS and GOARCH Self-contained binary (as long as you don't need Cgo)

Slide 14

Slide 14 text

HIERARCHY OF USER HIERARCHY OF USER INTERFACES INTERFACES Command Line Interface (CLI) Text-based User Interface (TUI) Graphical User Interface (GUI)

Slide 15

Slide 15 text

HIERARCHY OF USER HIERARCHY OF USER INTERFACES INTERFACES Command Line Interface (CLI) Text-based User Interface (TUI) ☜ Graphical User Interface (GUI)

Slide 16

Slide 16 text

PART 1 PART 1 ☞ CHARACTERS ☞ CHARACTERS

Slide 17

Slide 17 text

CARRIAGE RETURN CARRIAGE RETURN YOUR NEW SECRET WEAPON YOUR NEW SECRET WEAPON

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

BUILDING A PROGRESS BAR BUILDING A PROGRESS BAR

Slide 20

Slide 20 text

BUILDING A PROGRESS BAR BUILDING A PROGRESS BAR func drawBar(percent int) { cols := 10 prog := strings.Repeat("=", cols*percent/100.0) fmt.Printf("\rdemo progress: %3[1]d%% |%-[3]*[2]s|", percent, prog, cols) }

Slide 21

Slide 21 text

BUILDING A PROGRESS BAR (CON'T) BUILDING A PROGRESS BAR (CON'T) fmt.Printf("\rdemo progress: %3[1]d%% |%-[3]*[2]s|", percent, prog, cols)

Slide 22

Slide 22 text

BUILDING A PROGRESS BAR (CON'T) BUILDING A PROGRESS BAR (CON'T) \r Move to start of line fmt.Printf("\rdemo progress: %3[1]d%% |%-[3]*[2]s|", percent, prog, cols)

Slide 23

Slide 23 text

BUILDING A PROGRESS BAR (CON'T) BUILDING A PROGRESS BAR (CON'T) \r Move to start of line %3[1]d Print the int value of arg 1 fmt.Printf("\rdemo progress: %3[1]d%% |%-[3]*[2]s|", percent, prog, cols)

Slide 24

Slide 24 text

BUILDING A PROGRESS BAR (CON'T) BUILDING A PROGRESS BAR (CON'T) \r Move to start of line %3[1]d Print the int value of arg 1 %% Literal percent fmt.Printf("\rdemo progress: %3[1]d%% |%-[3]*[2]s|", percent, prog, cols)

Slide 25

Slide 25 text

BUILDING A PROGRESS BAR (CON'T) BUILDING A PROGRESS BAR (CON'T) \r Move to start of line %3[1]d Print the int value of arg 1 %% Literal percent -[3]* Left justify and pad by the value of arg 3 fmt.Printf("\rdemo progress: %3[1]d%% |%-[3]*[2]s|", percent, prog, cols)

Slide 26

Slide 26 text

BUILDING A PROGRESS BAR (CON'T) BUILDING A PROGRESS BAR (CON'T) \r Move to start of line %3[1]d Print the int value of arg 1 %% Literal percent -[3]* Left justify and pad by the value of arg 3 [2]s Print the string value of arg 2 fmt.Printf("\rdemo progress: %3[1]d%% |%-[3]*[2]s|", percent, prog, cols)

Slide 27

Slide 27 text

UNICODE UNICODE YOUR YOUR OTHER OTHER NEW SECRET WEAPON NEW SECRET WEAPON

Slide 28

Slide 28 text

UNICODE SPINNERS UNICODE SPINNERS Carriage return ❤ unicode

Slide 29

Slide 29 text

UNICODE SPINNERS UNICODE SPINNERS Carriage return ❤ unicode var ( braille = []rune{'⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', clock = []rune{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' )

Slide 30

Slide 30 text

SPICE UP YOUR USER SPICE UP YOUR USER INTERACTIONS INTERACTIONS ✅ Success! ⚠ Your password needs more entropy ???

Slide 31

Slide 31 text

WHAT C

Slide 32

Slide 32 text

MISSING CHARACTERS IN A MISSING CHARACTERS IN A TYPEFACE TYPEFACE missing := "The power symbol is new in Unicode 9:

Slide 33

Slide 33 text

MISCOUNTING MULTIBYTE MISCOUNTING MULTIBYTE CHARACTERS CHARACTERS miscounted := " " fmt.Println(miscounted, "has len", len(miscounted)) fmt.Println(miscounted, "has runes", utf8.RuneCount([]byte(miscounted))) has len 4 has runes 1

Slide 34

Slide 34 text

WIDE CHARACTERS WIDE CHARACTERS wide := " 十" fmt.Println(wide) fmt.Println("01") fmt.Println("runes:", utf8.RuneCount([]byte(wide))) fmt.Println("width:", runewidth.StringWidth(wide)) 十 01 runes: 1 width: 2

Slide 35

Slide 35 text

SINGLE-WIDTH CHARACTERS THAT SINGLE-WIDTH CHARACTERS THAT RENDER AS WIDE RENDER AS WIDE wrongWidth := "☛" fmt.Println(wrongWidth) fmt.Println("01") fmt.Println("runes:", utf8.RuneCount([]byte(wrongWidth))) fmt.Println("width:", runewidth.StringWidth(wrongWidth)) fmt.Printf("%sOver top\n", wrongWidth) ☛ 01 runes: 1 width: 1 ☛Over top

Slide 36

Slide 36 text

PART 2 PART 2 ☞ ESCAPE CODES ☞ ESCAPE CODES

Slide 37

Slide 37 text

In-band signalling that starts with \033[.

Slide 38

Slide 38 text

In-band signalling that starts with \033[. Thank you, American National Standards Institute!

Slide 39

Slide 39 text

TEXT DECORATION TEXT DECORATION AND COLOR AND COLOR

Slide 40

Slide 40 text

DECORATIONS DECORATIONS Mostly supported

Slide 41

Slide 41 text

CHARACTER SIZE CHARACTER SIZE Not well supported, but really neat!

Slide 42

Slide 42 text

COLOR COLOR So many options!

Slide 43

Slide 43 text

MULTILINE OUTPUT MULTILINE OUTPUT WITH CURSOR MOVEMENT WITH CURSOR MOVEMENT

Slide 44

Slide 44 text

LINEAR-FEEDBACK SHIFT REGISTER LINEAR-FEEDBACK SHIFT REGISTER SCREEN CLEARING SCREEN CLEARING http://fabiensanglard.net/fizzlefade/index.php

Slide 45

Slide 45 text

SO MUCH MORE! SO MUCH MORE! Relative cursor movement Partial screen clearing

Slide 46

Slide 46 text

INTERLUDE INTERLUDE ☞ CAN I USE... ☞ CAN I USE...

Slide 47

Slide 47 text

HOW BAD CAN IT BE? HOW BAD CAN IT BE? That's a teapot in ReGIS 0kc5N/d|NkuKboHmhDdc4_.f~Y`zTevNbsHipCjn3^`mZlVkkRdkPkkM` lLnlJkmIinIhoIlpImqIorImsJotJiuKkvKawLnwLdxMixMayMfyMjyM nyMoyMczMMgzMMMhzNNizNjzNhzOizOkzOizPjzPhzQfzQczQmyRjyRg yR`yShxSmwSmvSivS`vShuS`uSmtSftSctSlsTjsTesUlrVhrWdrXarY jqZbq[gp\ko]in^gm^cl^ej^dh]f[mcXbaT-f~O{IbxBlt2ZiqPjnEnk 1YjiLmg0^jfOdl@nl/QomCjo.VmqJet-_`wUzLa}D.b`,]obWieSchOi jMlKenJooIgqIdrJgsJctKotLguMluO`vPdvQkvQnvRawSgwShwTmwTa xTexTixTlxT`yTgySfySiySmyS`zSczRRRbzRRnyRRjyReyRayRlxRkx QfxQaxQlwQnwPiwPgwOawOovNivNgvMevM`vMkuLfuLntLjtLosLgsLi

Slide 48

Slide 48 text

HOW CAN WE TELL HOW CAN WE TELL WHAT IS WHAT IS SUPPORTED? SUPPORTED?

Slide 49

Slide 49 text

ENVIRONMENT VARIABLES ENVIRONMENT VARIABLES TERM=xterm-256color COLORTERM=truecolor Terminal specific values

Slide 50

Slide 50 text

TERMINFO TERMINFO A database of terminal names (from TERM) and capabilities that started in ncurses. Includes escape codes.

Slide 51

Slide 51 text

TERMINFO TERMINFO A database of terminal names (from TERM) and capabilities that started in ncurses. Includes escape codes. For better portability, use a terminfo database for in-band signalling.

Slide 52

Slide 52 text

RELY ON THE USER RELY ON THE USER Provide flags and configuration for color and interactivity

Slide 53

Slide 53 text

HANDLING WINDOWS HANDLING WINDOWS Windows 10 can enable VT processing For other versions, wrap the output and parse escape codes

Slide 54

Slide 54 text

WINDOWS SUBSYSTEM FOR WINDOWS SUBSYSTEM FOR LINUX LINUX ANSI escape codes and POSIX syscalls under Windows The console related APIS don't work across environments

Slide 55

Slide 55 text

PART 3 PART 3 ☞ SYSTEM CALLS ☞ SYSTEM CALLS

Slide 56

Slide 56 text

Out-of-band signalling through system calls.

Slide 57

Slide 57 text

Out-of-band signalling through system calls. Thank you, IEEE Computer Society

Slide 58

Slide 58 text

Out-of-band signalling through system calls. Thank you, IEEE Computer Society And Microsoft

Slide 59

Slide 59 text

DETECTING TERMINAL SIZE DETECTING TERMINAL SIZE Great for columnar output and wrapping.

Slide 60

Slide 60 text

MULTI-LINE INTERACTIVE MULTI-LINE INTERACTIVE INLINE INPUTS INLINE INPUTS Raw mode

Slide 61

Slide 61 text

PART 4 PART 4 ☞ POTPOURRI ☞ POTPOURRI

Slide 62

Slide 62 text

FULLSCREEN INTERFACES FULLSCREEN INTERFACES Combine: Raw mode Direct tty access Alternate buffer

Slide 63

Slide 63 text

DISPLAYING GRAPHICS DISPLAYING GRAPHICS SIXEL: raster graphics from DEC ReGIS: vector graphics from DEC Custom formats for assorted modern terminals

Slide 64

Slide 64 text

CAPTURING MOUSE INPUT CAPTURING MOUSE INPUT Broad support Not supported in Windows VT Processing. You have to fall back to the input buffer API.

Slide 65

Slide 65 text

APPENDIX APPENDIX ☞ LEARN MORE ☞ LEARN MORE

Slide 66

Slide 66 text

GREAT LIBRARIES GREAT LIBRARIES chzyer/readline manifoldco/promptui gdamore/tcell mattn/go-runewidth

Slide 67

Slide 67 text

READING LIST READING LIST Windows console reference ANSI escape codes termios(3) XTerm Control Sequences

Slide 68

Slide 68 text

THANK YOU! THANK YOU!  @jrbowes  this presentation (https://bit.ly/cli-ui)