-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtodo.red
235 lines (189 loc) · 8.95 KB
/
todo.red
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
227
228
229
230
231
232
233
234
Red [
Title: ".system.user.apps.jot.note.red"
Description: {quick note taking app with options to stay always on top and timestamp}
Github-Url: https://gist.github.com/lepinekong/346c45238ef0a75fb11f3986ed67e0c8
History: [
v1.0: [
.url: https://gist.githubusercontent.com/lepinekong/346c45238ef0a75fb11f3986ed67e0c8/raw/fec7f096f5f75c00159ccbbb6b97514d38a60ad3/.system.user.apps.jot.note.red
.description: {
### this version
- allows user to resize/maximize window
### TODO:
- option to ask confirmation for save on close
}
]
v0.9: [
.url: https://gist.githubusercontent.com/lepinekong/346c45238ef0a75fb11f3986ed67e0c8/raw/fec7f096f5f75c00159ccbbb6b97514d38a60ad3/.system.user.apps.jot.note.red
.description: {initial version
### which supports:
- topmost window (by default or use Jot/no-topmost)
- timestamp (by default or use Jot/no-timestamp)
- save on close
### TODO:
- allow user to resize/maximize window
- option to ask confirmation for save on close
}
]
]
Flowchart: [
Main: [
Jot -> Jot-already-launched? [
Yes: [Set-Jot-to-Foreground -> Jot-Launched]
No: [Launch-Jot -> load-note-file -> Jot-Launched]
]
]
Jot-Launched: [
Click-Save?: [Save-note-file -> Jot-Launched]
Date-Stamp?: [Append-Date-Stamp -> Jot-Launched]
Close?: [Save-note-file -> End]
]
]
]
>Window-Caption: "To do"
>out-filename: %.TODO
>out-folder: %./
;===========================================================================================
; PREAMBLE
;===========================================================================================
>builds: [
0.0.0.2.2.1 {initial version}
]
>Area-Size: 270x700
;self script path
script-path: system/options/script
;library
set-topmost: function [.hwnd-file /show][ ; uses win32 API
command: {function Set-TopMost($handle) {$FnDef = '[DllImport("user32.dll")] public static extern bool SetWindowPos(int hWnd, int hAfter, int x, int y, int cx, int cy, uint Flags);';$user32 = Add-Type -MemberDefinition $FnDef -Name 'User32' -Namespace 'Win32' -PassThru;$user32::SetWindowPos($handle, -1, 0,0,0,0, 3)};Add-Type 'using System;using System.Runtime.InteropServices;using System.Text; public class APIFuncs {[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]public static extern int GetWindowText(IntPtr hwnd,StringBuilder lpString, int cch);[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)] public static extern IntPtr GetForegroundWindow();[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)] public static extern Int32 GetWindowThreadProcessId(IntPtr hWnd,out Int32 lpdwProcessId);[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)] public static extern Int32 GetWindowTextLength(IntPtr hWnd);}';while(1){$w = [apifuncs]::GetForegroundWindow();Write-Host $w.toString();$len = [apifuncs]::GetWindowTextLength($w);$sb = New-Object text.stringbuilder -ArgumentList ($len + 1);$rtnlen = [apifuncs]::GetWindowText($w,$sb,$sb.Capacity);write-host "Window Title: $($sb.tostring())";$windowTitle=$sb.tostring();if ($windowTitle -eq "Jot Note:") {Set-TopMost($w);$w.toString() | Out-File -filepath ".hwnd-file" -Encoding "UTF8";exit};sleep 1}}
replace/all command {"} {\"}
replace command ".hwnd-file" (to-local-file .hwnd-file)
powershell-command: rejoin [{powershell -command} { } {"} command {"}]
either show [
call/show powershell-command ; if non gui console otherwise doesn't seem to work
][
call powershell-command ; if gui console otherwise show ugly powershell console
]
]
set-active-window: function[.hwnd][
command: {$sig = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);[DllImport("user32.dll")] public static extern int SetForegroundWindow(IntPtr hwnd);';if ($Maximize) { $Mode = 3 } else { $Mode = 4 };$type = Add-Type -MemberDefinition $sig -Name WindowAPI -PassThru;$hwnd = .hwnd;$null = $type::ShowWindowAsync($hwnd, $Mode);$null = $type::SetForegroundWindow($hwnd)}
replace/all command {"} {\"}
replace command ".hwnd" .hwnd
powershell-command: rejoin [{powershell -command} { } {"} command {"}]
call powershell-command
]
window-opened?: function[.window-title][
out: copy ""
call/output {powershell -command "Get-Process | Where-Object {$_.MainWindowTitle -ne \"\"} | Select-Object MainWindowTitle"} out
if find out .window-title [
return true
]
return false
]
;===========================================================================================
; PROGRAM
;===========================================================================================
.app.note: function [
/no-topmost
/no-timestamp
/folder >out-folder ; 0.0.0.1.7
/filename >out-filename ; 0.0.0.1.7
/_build >build ; 0.0.0.1.12
/silent
/local static-path
/extern note-file event-handler text-area resized-window resized-window-width; extern necessary when using view/no-wait
][
if _build [
unless silent [
?? >builds
]
return >builds
]
if not folder [
>out-folder: system/words/>out-folder
]
if not filename [
>out-filename: system/words/>out-filename
]
hwnd-file: rejoin [>out-folder %hwnd.txt] ; for passing back hwnd to Win32
note-file: rejoin [>out-folder >out-filename] ; for saving note file
info-path: to-local-file clean-path note-file
?? info-path
if window-opened? >window-caption [
; if Jot launched already, Set Jot to Foreground
if (exists? hwnd-file) [ ; hwnd file has been created to store Win32 window handle when Set-Topmost is called
hwnd: read hwnd-file ; have to read from a file as a layman's way to do interop
set-active-window hwnd ; Set Jot to Foreground calling win32
return false ; false means not created
]
]
Title: rejoin [>Window-Caption ":"] ; title of window bar
Area-Size: >Area-Size ; vertical jot note
note: copy rejoin ["# " now/date " " now/time ] ; date stamp
append note newline append note newline ; for nicer formatting
if (exists? note-file) [ ; first time note-file doesn't exist
note: read note-file
unless (note = "") [ append note newline]
unless no-timestamp [
append note rejoin ["# " now/date " " now/time ]
append note newline append note newline
]
]
on-events: func [face event /local static-counter] compose [
case [
'close = event/type [
write note-file text-area/text
remove-event-func :event-handler
return none
]
'resize = event/type [
static-counter: []; to fix a weird behavior in resize first time in some context (.system context)
either empty? static-counter [
append static-counter 0
][
static-counter/1: static-counter/1 + 1
unless ((value? '.system) and (static-counter/1 = 1)) [ ; to fix a weird behavior in resize first time in some context
resized-window: event/window
resized-window-width: first resized-window/size
text-area/size: to-pair rejoin [ (resized-window-width - 20) "x" (second text-area/size)]
]
]
]
]
return event
]
win: copy[]
append win compose/deep [
title (Title)
text-area: area (Area-Size) note
return
button "save" [
write note-file text-area/text
print "saved"
]
button "DateStamp" [
text-area/text: rejoin [text-area/text "# " now/date " " now/time newline newline]
]
do [ event-handler: insert-event-func :on-events ]
]
either (system/console = none) [
; for compiled version (no console)
unless no-topmost [set-topmost/show hwnd-file]
view/flags win ['resize]
][
either system/console/gui? [
; for interpreted version with gui console
unless no-topmost [set-topmost hwnd-file]
view/flags/no-wait win ['resize]
][
; for interpreted version with non-gui console (vscode)
unless no-topmost [set-topmost/show hwnd-file]
view/flags win ['resize]
]
]
]
Jot-Note: :.app.note ; alias
Jot: :.app.note ; alias
Note: :.app.note ; alias
todo: :.app.note ; alias
if not value? '.system [
todo
]