summary refs log tree commit diff stats
path: root/doc/uml
Commit message (Collapse)AuthorAgeFilesLines
* random cleanups and fixeshut2010-01-071-5/+6
|
* notify: merged into statusbar, allow to view the log in the pagerhut2010-01-013-35/+2
|
* cleanupshut2009-12-311-1/+5
|
* rename filelist(container) to browsercolumn/browserviewhut2009-12-313-38/+76
|
* updated uml projecthut2009-12-305-73/+215
|
* moved /uml to /doc/umlhut2009-12-2514-0/+2180
08130'>^
384fe0d ^
a073d76 ^
d35213e ^
a073d76 ^
d35213e ^
1170893 ^
661e3ec ^


1418e1b ^
661e3ec ^

6728a11 ^
a073d76 ^

d35213e ^
a073d76 ^


661e3ec ^

1418e1b ^
661e3ec ^








1418e1b ^
d35213e ^
80e891a ^

384fe0d ^
d35213e ^


661e3ec ^

1170893 ^







661e3ec ^
384fe0d ^


661e3ec ^





384fe0d ^
661e3ec ^


384fe0d ^
661e3ec ^


384fe0d ^
661e3ec ^


384fe0d ^
661e3ec ^




384fe0d ^

661e3ec ^




384fe0d ^

661e3ec ^




80e891a ^




661e3ec ^
80e891a ^
661e3ec ^
80e891a ^
661e3ec ^



80e891a ^
384fe0d ^
661e3ec ^


80e891a ^
661e3ec ^

80e891a ^
384fe0d ^
661e3ec ^
80e891a ^
661e3ec ^
80e891a ^
24dfc47 ^


a073d76 ^
80e891a ^
24dfc47 ^


a073d76 ^
8d20e92 ^

661e3ec ^



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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
               

        
                                  
                                       

                                          



                       


                    
                      
                                
                           
                      
                   
                    


                   
                                        

 
                                                                

                                
                            


                                  

 
                                                                  








                                      
                                         
                             

                                                                          
                                                                     


                                         

 







                                                                             
                                   


                                                                  





                                      
                                 


                         
                                 


                           
                                         


                             
                                                                       




                                

                                                                                      




                               

                                                                                      




                               




                                                             
                                      
                                                     
                                       
                                                   



                                               
                                                    
                                                       


                                               
                                                   

                                       
                                                  
                                                  
                                       
                                    
                                       
                                    


                                                   
                                                     
                                                  


                                                   
                                   

                                               



                   
package widgets

import (
	"github.com/gdamore/tcell"
	"github.com/mattn/go-runewidth"

	"git.sr.ht/~sircmpwn/aerc2/lib/ui"
)

// TODO: history
// TODO: tab completion
// TODO: scrolling

type ExLine struct {
	command []rune
	commit  func(cmd string)
	ctx     *ui.Context
	cancel  func()
	cells   int
	focus   bool
	index   int
	scroll  int

	onInvalidate func(d ui.Drawable)
}

func NewExLine(commit func(cmd string), cancel func()) *ExLine {
	return &ExLine{
		cancel:  cancel,
		cells:   -1,
		commit:  commit,
		command: []rune{},
	}
}

func (ex *ExLine) OnInvalidate(onInvalidate func(d ui.Drawable)) {
	ex.onInvalidate = onInvalidate
}

func (ex *ExLine) Invalidate() {
	if ex.onInvalidate != nil {
		ex.onInvalidate(ex)
	}
}

func (ex *ExLine) Draw(ctx *ui.Context) {
	ex.ctx = ctx // gross
	ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', tcell.StyleDefault)
	ctx.Printf(0, 0, tcell.StyleDefault, ":%s", string(ex.command))
	cells := runewidth.StringWidth(string(ex.command[:ex.index]))
	if cells != ex.cells {
		ctx.SetCursor(cells+1, 0)
	}
}

func (ex *ExLine) Focus(focus bool) {
	ex.focus = focus
	if focus && ex.ctx != nil {
		cells := runewidth.StringWidth(string(ex.command[:ex.index]))
		ex.ctx.SetCursor(cells+1, 0)
	}
}

func (ex *ExLine) insert(ch rune) {
	left := ex.command[:ex.index]
	right := ex.command[ex.index:]
	ex.command = append(left, append([]rune{ch}, right...)...)
	ex.index++
	ex.Invalidate()
}

func (ex *ExLine) deleteWord() {
	// TODO: Break on any of / " '
	if len(ex.command) == 0 {
		return
	}
	i := ex.index - 1
	if ex.command[i] == ' ' {
		i--
	}
	for ; i >= 0; i-- {
		if ex.command[i] == ' ' {
			break
		}
	}
	ex.command = append(ex.command[:i+1], ex.command[ex.index:]...)
	ex.index = i + 1
	ex.Invalidate()
}

func (ex *ExLine) deleteChar() {
	if len(ex.command) > 0 && ex.index != len(ex.command) {
		ex.command = append(ex.command[:ex.index], ex.command[ex.index+1:]...)
		ex.Invalidate()
	}
}

func (ex *ExLine) backspace() {
	if len(ex.command) > 0 && ex.index != 0 {
		ex.command = append(ex.command[:ex.index-1], ex.command[ex.index:]...)
		ex.index--
		ex.Invalidate()
	}
}

func (ex *ExLine) Event(event tcell.Event) bool {
	switch event := event.(type) {
	case *tcell.EventKey:
		switch event.Key() {
		case tcell.KeyBackspace, tcell.KeyBackspace2:
			ex.backspace()
		case tcell.KeyCtrlD, tcell.KeyDelete:
			ex.deleteChar()
		case tcell.KeyCtrlB, tcell.KeyLeft:
			if ex.index > 0 {
				ex.index--
				ex.Invalidate()
			}
		case tcell.KeyCtrlF, tcell.KeyRight:
			if ex.index < len(ex.command) {
				ex.index++
				ex.Invalidate()
			}
		case tcell.KeyCtrlA, tcell.KeyHome:
			ex.index = 0
			ex.Invalidate()
		case tcell.KeyCtrlE, tcell.KeyEnd:
			ex.index = len(ex.command)
			ex.Invalidate()
		case tcell.KeyCtrlW:
			ex.deleteWord()
		case tcell.KeyEnter:
			if ex.ctx != nil {
				ex.ctx.HideCursor()
			}
			ex.commit(string(ex.command))
		case tcell.KeyEsc, tcell.KeyCtrlC:
			if ex.ctx != nil {
				ex.ctx.HideCursor()
			}
			ex.cancel()
		case tcell.KeyRune:
			ex.insert(event.Rune())
		}
	}
	return true
}