-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathorganizer.go
More file actions
226 lines (201 loc) · 6.16 KB
/
organizer.go
File metadata and controls
226 lines (201 loc) · 6.16 KB
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
package main
import (
"fmt"
"sort"
"github.com/slzatz/vimango/vim"
"github.com/slzatz/vimango/vim/interfaces"
)
// RedrawScope represents the extent of organizer redraw work required after a key event.
type RedrawScope int
const (
RedrawNone RedrawScope = iota
RedrawPartial
RedrawFull
)
type Organizer struct {
mode Mode
//last_mode Mode
cx, cy int //cursor x and y position
fc, fr int // file x and y position
rowoff int //the number of rows scrolled (aka number of top rows now off-screen
altRowoff int //the number of rows scrolled in the right window (aka number of top rows now off-screen)
coloff int //the number of columns scrolled (aka number of left rows now off-screen
rows []Row
altRows []AltRow
altFr int
filter string
sort string
sortPriority bool
command_line string
message string
note []string // the preview
notice []string // e.g., synch results, help test, research notification
command string
show_deleted bool
show_completed bool
view View
altView View //int
taskview int
current_task_id int
string_buffer string
marked_entries map[int]struct{} // map instead of list makes toggling a row easier
title_search_string string
highlight [2]int
vbuf interfaces.VimBuffer
bufferTick int
//saveTick int
normalCmds map[string]func(*Organizer)
exCmds map[string]func(*Organizer, int)
commandRegistry *CommandRegistry[func(*Organizer, int)]
normalCommandRegistry *CommandRegistry[func(*Organizer)]
filterList []FilterNames
containerList []string
tabCompletion struct {
list []FilterNames
index int
}
Database *Database
Session *Session
Screen *Screen
}
type FilterNames struct {
Text string
Char rune
}
func (a *App) setFilterList() []FilterNames {
fnlist := []FilterNames{}
filterMap := a.Database.contextList()
for v, _ := range filterMap {
fnlist = append(fnlist, FilterNames{Text: v, Char: 'c'})
}
filterMap = a.Database.folderList()
for v, _ := range filterMap {
fnlist = append(fnlist, FilterNames{Text: v, Char: 'f'})
}
sort.Slice(fnlist, func(i, j int) bool {
return fnlist[i].Text < fnlist[j].Text
})
return fnlist
}
func (o *Organizer) FilterEntries(max int) {
var err error
o.rows, err = o.Database.filterEntries(o.taskview, o.filter, o.show_deleted, o.sort, o.sortPriority, max)
if err != nil {
o.showMessage("Error filtering entries: %v", err)
}
}
func (o *Organizer) getId() int {
return o.rows[o.fr].id
}
func (o *Organizer) readRowsIntoBuffer() {
// Create a new clean slice for titles
numRows := len(o.rows)
ss := make([]string, numRows)
for i, row := range o.rows {
ss[i] = row.title
}
// If we're using Go implementation and have titles
if vim.GetActiveImplementation() == vim.ImplGo {
// Create a completely new buffer for maximum safety with Go implementation
buf := vim.NewBuffer(0)
// Handle the special case where we have no rows
if len(ss) == 0 {
// Always ensure at least an empty line for consistent behavior
ss = []string{""}
}
// Set the new buffer's lines - use a defensive approach
deepCopy := make([]string, len(ss))
for i, line := range ss {
deepCopy[i] = line // Deep copy to ensure no shared references
}
// Set the lines in the buffer
buf.SetLines(0, -1, deepCopy)
// Make it the current buffer and store the reference
buf.SetCurrent()
o.vbuf = buf
} else {
// Standard approach for C implementation
if o.vbuf == nil {
// This shouldn't happen, but handle it gracefully
o.vbuf = vim.NewBuffer(0)
}
// Ensure we have at least an empty line in empty cases
if len(ss) == 0 {
ss = []string{""}
}
// Update the existing buffer's content
o.vbuf.SetLines(0, -1, ss)
vim.SetCurrentBuffer(o.vbuf)
}
}
func (o *Organizer) showMessage(format string, a ...interface{}) {
fmt.Printf("\x1b[%d;%dH\x1b[1K\x1b[%d;1H", o.Screen.textLines+2+TOP_MARGIN, o.Screen.divider, o.Screen.textLines+2+TOP_MARGIN)
str := fmt.Sprintf(format, a...)
if len(str) > o.Screen.divider {
str = str[:o.Screen.divider]
}
fmt.Print(str)
}
func (o *Organizer) ShowMessage(loc Location, format string, a ...interface{}) {
max_length := o.Screen.PositionMessage(loc)
str := fmt.Sprintf(format, a...)
// breakWord breaks strings (can be several words) into first segment
// that fits taking into acount ANSI escape codes
ss := breakWord(str, max_length)[0]
str = ss + RESET
fmt.Print(str)
}
func (o *Organizer) setContextNew(input string) {
var contextUUID string
var ok bool
//o.mode = NORMAL
if contextUUID, ok = o.Database.contextExists(input); !ok {
o.ShowMessage(BL, "%s is not a valid context!", input)
return
}
if len(o.marked_entries) > 0 {
for id := range o.marked_entries {
err := o.Database.updateTaskContextByUUID(contextUUID, id)
if err != nil {
o.ShowMessage(BL, "Error updating context for entry %d: %v", id, err)
return
}
}
o.ShowMessage(BL, "Marked entries moved into context %q", input)
return
}
id := o.rows[o.fr].id
err := o.Database.updateTaskContextByUUID(contextUUID, id)
if err != nil {
o.showMessage("Error updating context for entry %d: %v", id, err)
return
}
o.ShowMessage(BL, "Moved current entry into context %q", input)
}
func (o *Organizer) setFolderNew(input string) {
var folderUUID string
var ok bool
//o.mode = NORMAL
if folderUUID, ok = o.Database.folderExists(input); !ok {
o.ShowMessage(BL, "%s is not a valid folder!", input)
return
}
if len(o.marked_entries) > 0 {
for id := range o.marked_entries {
err := o.Database.updateTaskFolderByUUID(folderUUID, id)
if err != nil {
o.ShowMessage(BL, "Error updating folder for entry %d: %v", id, err)
return
}
}
o.ShowMessage(BL, "Marked entries moved into folder %q", input)
return
}
id := o.rows[o.fr].id
err := o.Database.updateTaskFolderByUUID(folderUUID, id)
if err != nil {
o.showMessage("Error updating folder for entry %d: %v", id, err)
return
}
o.ShowMessage(BL, "Moved current entry into folder %q", input)
}