poco_update_state.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
function Update-State ($state, $config, $action, $key) {
    switch ($action) {
        'AddChar'             {Add-Char $state $config $key.KeyChar}
        'ForwardChar'         {Move-ForwardChar $state}
        'BackwardChar'        {Move-BackwardChar $state}
        'BeginningOfLine'     {Move-BeginningOfLine $state}
        'EndOfLine'           {Move-EndOfLine $state}
        'DeleteBackwardChar'  {Remove-BackwardChar $state}
        'DeleteForwardChar'   {Remove-ForwardChar $state}
        'KillBeginningOfLine' {Remove-HeadLine $state}
        'KillEndOfLine'       {Remove-TailLine $state}
        'RotateMatcher'       {Select-Matcher $state}
        'ToggleCaseSensitive' {Switch-CaseSensitive $state}
        'ToggleInvertFilter'  {Switch-InvertFilter $state}
        
        default {} # None, Cancel, Finish = identity
    }
    
    $state
}

function Add-Char ($state, $config, $char) {
    $x = $state.Screen.QueryX
    $q = $state.Query

    $state.Query = $q.Insert($x, $char)
    $state.Screen.QueryX++
    $state.Screen.X++

    $state.Screen.Prompt = Get-Prompt $state $config
}

function Move-BackwardChar ($state) {
    $x = $state.Screen.QueryX
    if ($x - 1 -ge 0) {
        $state.Screen.QueryX--
        $state.Screen.X--
    }
}

function Move-ForwardChar ($state) {
    $x = $state.Screen.X
    $l = $state.Screen.Prompt.length

    if ($x + 1 -le $l) {
        $state.Screen.QueryX++
        $state.Screen.X++
    }
}

function Move-BeginningOfLine ($state) {
    $state.Screen.X -= $state.Screen.QueryX
    $state.Screen.QueryX = 0
}

function Move-EndOfLine ($state) {
    $state.Screen.QueryX = $state.Query.length
    $state.Screen.X = $state.Screen.Prompt.length
}

function Remove-BackwardChar ($state) {
    $x = $state.Screen.QueryX
    $q = $state.Query
    
    if ($x - 1 -ge 0) {
        $state.Query = $q.Remove($x - 1, 1)
        $state.Screen.QueryX--
        $state.Screen.X--

        $state.Screen.Prompt = Get-Prompt $state $config
    }
}

function Remove-ForwardChar ($state) {
    $x = $state.Screen.X
    $l = $state.Screen.Prompt.length

    $qx = $state.Screen.QueryX
    $q = $state.Query

    if ($x + 1 -le $l) {
        $state.Query = $q.Remove($qx, 1)
        $state.Screen.Prompt = Get-Prompt $state $config
    }
}

function Remove-HeadLine ($state) {
    while ($state.Screen.QueryX -gt 0) {
        Remove-BackwardChar ($state)
    }
}

function Remove-TailLine ($state) {
    while ($state.Screen.QueryX -lt $state.Query.length) {
        Remove-ForwardChar ($state)
    }
}

function Select-Matcher ($state) {
    $arr = @('match', 'like', 'eq')

    $n = $arr.length
    $i = $arr.IndexOf($state.Filter) + 1

    $state.Filter = $arr[$i % $n]

    $state.Screen.FilterType = Get-FilterType $state
}

function Switch-CaseSensitive ($state) {
    $state.CaseSensitive = -not $state.CaseSensitive
    $state.Screen.FilterType = Get-FilterType $state
}

function Switch-InvertFilter ($state) {
    $state.InvertFilter = -not $state.InvertFilter
    $state.Screen.FilterType = Get-FilterType $state
}