about summary refs log tree commit diff stats
path: root/widgets/exline.go
blob: 692c8e2136669d4b171f5cc6bc13c4002279a42d (plain) (blame)
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
package widgets

import (
	"github.com/gdamore/tcell"

	"git.sr.ht/~sircmpwn/aerc/config"
	"git.sr.ht/~sircmpwn/aerc/lib"
	"git.sr.ht/~sircmpwn/aerc/lib/ui"
)

type ExLine struct {
	ui.Invalidatable
	commit      func(cmd string)
	finish      func()
	tabcomplete func(cmd string) []string
	cmdHistory  lib.History
	input       *ui.TextInput
	conf        *config.AercConfig
}

func NewExLine(conf *config.AercConfig, cmd string, commit func(cmd string), finish func(),
	tabcomplete func(cmd string) []string,
	cmdHistory lib.History) *ExLine {

	input := ui.NewTextInput("", conf.Ui).Prompt(":").Set(cmd)
	if conf.Ui.CompletionPopovers {
		input.TabComplete(tabcomplete, conf.Ui.CompletionDelay)
	}
	exline := &ExLine{
		commit:      commit,
		finish:      finish,
		tabcomplete: tabcomplete,
		cmdHistory:  cmdHistory,
		input:       input,
		conf:        conf,
	}
	input.OnInvalidate(func(d ui.Drawable) {
		exline.Invalidate()
	})
	return exline
}

func NewPrompt(conf *config.AercConfig, prompt string, commit func(text string),
	tabcomplete func(cmd string) []string) *ExLine {

	input := ui.NewTextInput("", conf.Ui).Prompt(prompt)
	if conf.Ui.CompletionPopovers {
		input.TabComplete(tabcomplete, conf.Ui.CompletionDelay)
	}
	exline := &ExLine{
		commit:      commit,
		tabcomplete: tabcomplete,
		cmdHistory:  &nullHistory{input: input},
		input:       input,
	}
	input.OnInvalidate(func(d ui.Drawable) {
		exline.Invalidate()
	})
	return exline
}

func (ex *ExLine) Invalidate() {
	ex.DoInvalidate(ex)
}

func (ex *ExLine) Draw(ctx *ui.Context) {
	ex.input.Draw(ctx)
}

func (ex *ExLine) Focus(focus bool) {
	ex.input.Focus(focus)
}

func (ex *ExLine) Event(event tcell.Event) bool {
	switch event := event.(type) {
	case *tcell.EventKey:
		switch event.Key() {
		case tcell.KeyEnter, tcell.KeyCtrlJ:
			cmd := ex.input.String()
			ex.input.Focus(false)
			ex.commit(cmd)
			ex.finish()
		case tcell.KeyUp:
			ex.input.Set(ex.cmdHistory.Prev())
			ex.Invalidate()
		case tcell.KeyDown:
			ex.input.Set(ex.cmdHistory.Next())
			ex.Invalidate()
		case tcell.KeyEsc, tcell.KeyCtrlC:
			ex.input.Focus(false)
			ex.cmdHistory.Reset()
			ex.finish()
		default:
			return ex.input.Event(event)
		}
	}
	return true
}

type nullHistory struct {
	input *ui.TextInput
}

func (*nullHistory) Add(string) {}

func (h *nullHistory) Next() string {
	return h.input.String()
}

func (h *nullHistory) Prev() string {
	return h.input.String()
}

func (*nullHistory) Reset() {}
> 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
120
121
122
123
124
125
126
127
128
129
130
131














                                                                                                 
                              
                              


                             

                               














                                                                                    
                    
                                                                          


                                         





                                                                                                                          
                         




                                                                                                                                               

   


                                                             
                    
   


                                                                                                                                        

                         

                                                                                                                                          
                         
                                                                                                                                                                                              




                                                                         
                    
                                                                                                         
   


                                                                                                                                        

                         

                                                                                                                                          
                         
                                                                                                                                                                                              




                                                                                       
                    

                                                                                                         


                                         


                                                                                                                                        

                         



                                                                                                                                           

                               

                                                                                                                                                                                              


   
                                                                                                                                    

                                                

                                                                                                          
                                  
                                                                             
                                                 
                                                        

                                       
                                                                 
 



                                     
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 090scenario_filesystem_test.mu</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="none">
<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 12pt; font-size: 1em; }
.Delimiter { color: #800080; }
.muControl { color: #c0a020; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #c00000; }
.muRecipe { color: #ff8700; }
.muScenario { color: #00af00; }
-->
</style>

<script type='text/javascript'>
<!--

-->
</script>
</head>
<body>
<pre id='vimCodeElement'>
<span class="Comment"># Check our support for fake file systems in scenarios.</span>

<span class="muScenario">scenario</span> read-from-fake-file [
  <span class="Constant">local-scope</span>
  assume-resources [
    <span class="Constant">[a]</span> <span class="Special">&lt;-</span> [
<span class="Constant">      |xyz|</span>
    ]
  ]
  contents:&amp;:source:char <span class="Special">&lt;-</span> start-reading resources, <span class="Constant">[a]</span>
  1:char/<span class="Special">raw</span> <span class="Special">&lt;-</span> read contents
  2:char/<span class="Special">raw</span> <span class="Special">&lt;-</span> read contents
  3:char/<span class="Special">raw</span> <span class="Special">&lt;-</span> read contents
  4:char/<span class="Special">raw</span> <span class="Special">&lt;-</span> read contents
  _, 5:bool/<span class="Special">raw</span> <span class="Special">&lt;-</span> read contents
  memory-should-contain [
   <span class="Constant"> 1</span> <span class="Special">&lt;-</span><span class="Constant"> 120</span>  <span class="Comment"># x</span>
   <span class="Constant"> 2</span> <span class="Special">&lt;-</span><span class="Constant"> 121</span>  <span class="Comment"># y</span>
   <span class="Constant"> 3</span> <span class="Special">&lt;-</span><span class="Constant"> 122</span>  <span class="Comment"># z</span>
   <span class="Constant"> 4</span> <span class="Special">&lt;-</span><span class="Constant"> 10</span>  <span class="Comment"># newline</span>
   <span class="Constant"> 5</span> <span class="Special">&lt;-</span><span class="Constant"> 1</span>  <span class="Comment"># eof</span>
  ]
]

<span class="muScenario">scenario</span> write-to-fake-file [
  <span class="Constant">local-scope</span>
  assume-resources [
  ]
  sink:&amp;:sink:char, writer:num/routine <span class="Special">&lt;-</span> start-writing resources, <span class="Constant">[a]</span>
  sink <span class="Special">&lt;-</span> write sink, <span class="Constant">120/x</span>
  sink <span class="Special">&lt;-</span> write sink, <span class="Constant">121/y</span>
  close sink
  wait-for-routine writer
  contents-read-back:text <span class="Special">&lt;-</span> slurp resources, <span class="Constant">[a]</span>
  10:bool/<span class="Special">raw</span> <span class="Special">&lt;-</span> equal contents-read-back, <span class="Constant">[xy]</span>
  memory-should-contain [
   <span class="Constant"> 10</span> <span class="Special">&lt;-</span><span class="Constant"> 1</span>  <span class="Comment"># file contents read back exactly match what was written</span>
  ]
]

<span class="muScenario">scenario</span> write-to-fake-file-that-exists [
  <span class="Constant">local-scope</span>
  assume-resources [
    <span class="Constant">[a]</span> <span class="Special">&lt;-</span> <span class="Constant">[]</span>
  ]
  sink:&amp;:sink:char, writer:num/routine <span class="Special">&lt;-</span> start-writing resources, <span class="Constant">[a]</span>
  sink <span class="Special">&lt;-</span> write sink, <span class="Constant">120/x</span>
  sink <span class="Special">&lt;-</span> write sink, <span class="Constant">121/y</span>
  close sink
  wait-for-routine writer
  contents-read-back:text <span class="Special">&lt;-</span> slurp resources, <span class="Constant">[a]</span>
  10:bool/<span class="Special">raw</span> <span class="Special">&lt;-</span> equal contents-read-back, <span class="Constant">[xy]</span>
  memory-should-contain [
   <span class="Constant"> 10</span> <span class="Special">&lt;-</span><span class="Constant"> 1</span>  <span class="Comment"># file contents read back exactly match what was written</span>
  ]
]

<span class="muScenario">scenario</span> write-to-existing-file-preserves-other-files [
  <span class="Constant">local-scope</span>
  assume-resources [
    <span class="Constant">[a]</span> <span class="Special">&lt;-</span> <span class="Constant">[]</span>
    <span class="Constant">[b]</span> <span class="Special">&lt;-</span> [
<span class="Constant">      |bcd|</span>
    ]
  ]
  sink:&amp;:sink:char, writer:num/routine <span class="Special">&lt;-</span> start-writing resources, <span class="Constant">[a]</span>
  sink <span class="Special">&lt;-</span> write sink, <span class="Constant">120/x</span>
  sink <span class="Special">&lt;-</span> write sink, <span class="Constant">121/y</span>
  close sink
  wait-for-routine writer
  contents-read-back:text <span class="Special">&lt;-</span> slurp resources, <span class="Constant">[a]</span>
  10:bool/<span class="Special">raw</span> <span class="Special">&lt;-</span> equal contents-read-back, <span class="Constant">[xy]</span>
  other-file-contents:text <span class="Special">&lt;-</span> slurp resources, <span class="Constant">[b]</span>
  11:bool/<span class="Special">raw</span> <span class="Special">&lt;-</span> equal other-file-contents, <span class="Constant">[bcd</span>
<span class="Constant">]</span>
  memory-should-contain [
   <span class="Constant"> 10</span> <span class="Special">&lt;-</span><span class="Constant"> 1</span>  <span class="Comment"># file contents read back exactly match what was written</span>
   <span class="Constant"> 11</span> <span class="Special">&lt;-</span><span class="Constant"> 1</span>  <span class="Comment"># other files also continue to persist unchanged</span>
  ]
]

<span class="muRecipe">def</span> slurp resources:&amp;:resources, filename:text<span class="muRecipe"> -&gt; </span>contents:text [
  <span class="Constant">local-scope</span>
  <span class="Constant">load-ingredients</span>
  source:&amp;:source:char <span class="Special">&lt;-</span> start-reading resources, filename
  buf:&amp;:buffer <span class="Special">&lt;-</span> new-buffer <span class="Constant">30/capacity</span>
  <span class="Delimiter">{</span>
    c:char, done?:bool, source <span class="Special">&lt;-</span> read source
    <span class="muControl">break-if</span> done?
    buf <span class="Special">&lt;-</span> append buf, c
    <span class="muControl">loop</span>
  <span class="Delimiter">}</span>
  contents <span class="Special">&lt;-</span> buffer-to-array buf
]
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->