forked from lintalist/lintalist
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lintanote.ahk
2709 lines (2415 loc) · 76.7 KB
/
lintanote.ahk
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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
Name : LintaNote
Author : LintaNote
Purpose : Searchable flate note keeper
Version : 0.0.0.1
Code : ComingSoon
Website : COmingSoon/
License : Copyright (c) 2009-2019 Lintalist + Public Domain Changes
This program is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
See license.txt for further details.
*/
; Default settings
#NoEnv
#SingleInstance, force
SetBatchLines, -1
SetTitleMatchMode, 2
ListLines, off
TmpDir:= A_ScriptDir "\tmpscrpts"
CoordMode, ToolTip, Screen
SendMode, Input
;SetKeyDelay, -1
SetWorkingDir, %A_ScriptDir%
FileEncoding, UTF-8
SortDirection:="Sort"
IniFile:="Settings.ini"
PluginMultiCaret:=0 ; TODOMC
; Title + Version are included in Title and used in #IfWinActive hotkeys and WinActivate
Title=LintaNote
Version=0.0.0.1
; Gosub, ReadPluginSettings
AppWindow=%title% - %version% ; Name of Gui
If A_IsAdmin
AppWindow:=A_UserName "^ " AppWindow
GroupAdd, AppTitle, %AppWindow% ; we can now use #IfWinActive with the INI value (main scripts hotkeys)
GroupAdd, BundleHotkeys, Select bundle ahk_class AutoHotkeyGUI
GroupAdd, BundleHotkeys, Append snippet to bundle ahk_class AutoHotkeyGUI
GroupAdd, BundleHotkeys, Select and press enter ahk_class AutoHotkeyGUI
GroupAdd, BundleHotkeys, Lintalist bundle editor ahk_class AutoHotkeyGUI
GroupAdd, BundleHotkeys, Lintalist snippet editor ahk_class AutoHotkeyGUI
GroupAdd, BundleHotkeys, Lintalist counters editor ahk_class AutoHotkeyGUI
GroupAdd, BundleHotkeys, Lintalist local bundle editor ahk_class AutoHotkeyGUI
GroupAdd, BundleHotkeys, Lintalist settings ahk_class AutoHotkeyGUI
OnExit, SaveSettings ; store settings (locked state, search mode, gui size etc in INI + Make sure changes to Bundles are saved)
; /Default settings
; Tray Menu
Menu, Tray, NoStandard
Menu, Tray, Icon, icons\lintalist_suspended.ico ; while loading show suspended icon
Menu, Tray, Add, %AppWindow%, GlobalMenuHandler
Menu, Tray, Icon, %AppWindow%, icons\lintalist.ico
Menu, Tray, Default, %AppWindow%
Menu, Tray, Add,
Menu, Tray, Add, &About, GlobalMenuHandler
Menu, Tray, Icon,&About, icons\help.ico
Menu, Tray, Add,
Menu, Tray, Add, &Configuration, GlobalMenuHandler
Menu, Tray, Icon,&Configuration, icons\gear.ico
Menu, Tray, Add, &Open Lintalist folder, GlobalMenuHandler
Menu, Tray, Icon,&Open Lintalist folder, icons\folder-horizontal-open.ico
Menu, Tray, Add, &View Statistics, GlobalMenuHandler
Menu, Tray, Icon,&View Statistics, icons\chart_pie.ico
Menu, Tray, Add,
Menu, Tray, Add, &Manage Bundles, GlobalMenuHandler
Menu, Tray, Icon,&Manage Bundles, icons\lintalist_bundle.ico
Menu, Tray, Add,
Menu, Tray, Add, &Load All Bundles, MenuHandler ; exception
Menu, Tray, Icon,&Load All Bundles, icons\arrow-in.ico
Menu, Tray, Add,
Menu, Tray, Add, &Pause Lintalist, GlobalMenuHandler
Menu, Tray, Icon,&Pause Lintalist, icons\control-pause.ico
Menu, Tray, Add,
Menu, Tray, Add, E&xit, GlobalMenuHandler
Menu, Tray, Icon,E&xit, icons\101_exit.ico
Menu, Tray, Check, &Pause Lintalist ; indicate program is still loading
Menu, Tray, Tip, %AppWindow% - inactive
; Tray Menu continue below
; Tray Menu left click handler
OnMessage(0x404, "AHK_NOTIFYICON")
; Includes
; [Note: bundle editor + plugins + GuiSettings included at the end of the script]
#Include %A_ScriptDir%\include\ObjectBundles.ahk
#Include %A_ScriptDir%\include\StayOnMonitor.ahk
#Include %A_ScriptDir%\include\ReadINI.ahk
#Include %A_ScriptDir%\include\Default.ahk
#Include %A_ScriptDir%\include\Func_IniSettingsEditor_v6.ahk
; /Includes
; command line parameters
if 0 > 0 ; check cl parameters
{
Loop, %0% ; For each parameter:
{
param := %A_Index% ; Fetch the contents of the variable whose name is contained in A_Index.
if (param = "-Active")
cl_Active:=1
if (param = "-ReadOnly") ; possible to expand to various options, see discussion https://github.com/lintalist/lintalist/issues/95
{
cl_ReadOnly:=1
AppWindow:="*" AppWindow
}
if (param = "-Administrator")
{
cl_Administrator:=1
AppWindow:=A_UserName "^ " AppWindow
}
if InStr(param,"-Bundle")
{
cl_Bundle:=StrSplit(param,"=").2
If !FileExist(A_ScriptDir "\bundles\" cl_Bundle)
cl_Bundle:=""
}
if InStr(param,"-Ini")
IniFile:=StrSplit(param,"=").2
param:=""
}
}
; /command line parameters
; INI ---------------------------------------
ReadIni()
If (Administrator = 1) or (cl_Administrator = 1)
{
Administrator:=1
If !A_IsAdmin
Gosub, RunAdmin
}
ReadMultiCaretIni()
ReadAltPasteIni()
ReadLineFeedIni()
If Statistics
Statistics()
Else
{
Menu, Tray, Disable, &View Statistics
}
if cl_Bundle
{
LastBundle:=cl_Bundle
Lock:=1
}
Gosub, ChoiceWindowPosition ; for choice plugin
Gosub, EditorWindowPosition ; for snippet editor
Gosub, CheckShortcuts
; Tray Menu settings
If (LoadAll = 1)
Menu, tray, Check, &Load All Bundles
Else If (LoadAll = 0)
Menu, tray, UnCheck, &Load All Bundles
If (ShorthandPaused = 1)
Menu, tray, Check, Pause &Shorthand
If (ShortcutPaused = 1)
Menu, tray, Check, Pause &Shortcut
If (ScriptPaused = 1)
Menu, tray, Check, Pause &Scripts
; /Tray Menu
; Dynamic Gui elements, postions etc.
Gosub, GuiStartupSettings
; /Dynamic Gui settings
PastText1=1
LoadAllBundles()
LoadPersonalBundle()
Menu, Tray, Icon, icons\lintalist.ico ; loading is done so show active Icon
Menu, tray, UnCheck, &Pause Lintalist
Menu, tray, Tip, %AppWindow% - active`nPress %StartSearchHotkey% to start search...
if (MinLen > 1)
MinLen--
Gosub, BuildFileMenu
Gosub, BuildEditMenu
Gosub, BuildEditorMenu
Gosub, QuickStartGuide
; setup hotkey
; check capslock and scrolllock status so we can actually use them as hotkey if defined by user and
; they are already in the DOWN (active) state when Lintalist is started
ProgramHotKeyList:="StartSearchHotkey,StartOmniSearchHotkey,QuickSearchHotkey,ExitProgramHotKey"
Loop, parse, ProgramHotKeyList, CSV
{
If (%A_LoopField% = "CAPSLOCK") and (GetKeyState("CAPSLOCK","T") = 1) ; is set as hotkey, so we need to turn it off
{
SetCapsLockState, Off
MsgBox, 64, Lintalist, Capslock has been turned off as it is now used by Lintalist.
}
If (%A_LoopField% = "SCROLLLOCK") and (GetKeyState("SCROLLLOCK","T") = 1)
{
SetScrollLockState, Off
MsgBox, 64, Lintalist, ScrollLock has been turned off as it is now used by Lintalist.
}
}
Hotkey, IfWinNotExist, ahk_group BundleHotkeys
Hotkey, %StartSearchHotkey%, GUIStart
If (StartOmniSearchHotkey <> "")
Hotkey, %StartOmniSearchHotkey%, GUIStartOmni
If (QuickSearchHotkey <> "")
Hotkey, %QuickSearchHotkey%, ShortText
If (ExitProgramHotKey <> "")
Hotkey, %ExitProgramHotKey%, SaveSettings
Hotkey, IfWinNotExist
ProgramHotKeyList:=""
ViaShorthand=0
; Toolbar setup
; Create an ImageList.
ILA := IL_CreateCustom(17, 5, IconSize) ; TODO BIGICONS
IL_Add(ILA, "icons\snippet_new.ico")
IL_Add(ILA, "icons\snippet_edit.ico")
IL_Add(ILA, "icons\snippet_copy.ico")
IL_Add(ILA, "icons\scripts.ico")
IL_Add(ILA, "icons\hotkeys.ico")
IL_Add(ILA, "icons\shorthand.ico")
IL_Add(ILA, "icons\lettervariations.ico")
IL_Add(ILA, "icons\unlocked.ico")
IL_Add(ILA, "icons\case.ico")
IL_Add(ILA, "icons\search_1.ico")
IL_Add(ILA, "icons\search_2.ico")
IL_Add(ILA, "icons\search_3.ico")
IL_Add(ILA, "icons\search_4.ico")
IL_Add(ILA, "icons\locked.ico")
IL_Add(ILA, "icons\no_scripts.ico")
IL_Add(ILA, "icons\no_hotkeys.ico")
IL_Add(ILA, "icons\no_shorthand.ico")
MyToolbarIcons:={ "UnLocked" : "8"
, "Locked" : "14"
, "Scripts" : "4"
, "NoScripts" : "15"
, "Hotkeys" : "5"
, "NoHotkeys" : "16"
, "ShortHand" : "6"
, "NoShortHand" : "17" }
; https://autohotkey.com/board/topic/94750-class-toolbar-create-and-modify-updated-19-08-2013/?p=599930
IL_CreateCustom(InitialCount=17, GrowCount=5, IconSize=16)
{
return DllCall("ImageList_Create"
, "Int", IconSize
, "Int", IconSize
, "UInt", 0x00000001 + 0x00000020
, "Int", InitialCount
, "Int", GrowCount)
}
; /Toolbar setup
; Listview ColorList
lvc:={1: "0xF5F5E2", 2: "0xF9F5EC", 3: "0xF9F3EC", 4: "0xF9EFEC", 5: "0xF5E8E2", 6: "0xFAF2EF", 7: "0xF8F1F1", 8: "0xFFEAEA", 9: "0xFAE7EC", 10: "0xFFE3FF", 11: "0xF8E9FC", 12: "0xEEEEFF", 13: "0xEFF9FC", 14: "0xF2F9F8", 15: "0xFFECEC", 16: "0xFFEEFB", 17: "0xFFECF5", 18: "0xFFEEFD", 19: "0xFDF2FF", 20: "0xFAECFF", 21: "0xF1ECFF", 22: "0xFFECFF", 23: "0xF4D2F4", 24: "0xF9EEFF", 25: "0xF5EEFD", 26: "0xEFEDFC", 27: "0xEAF1FB", 28: "0xDBF0F7", 29: "0xEEEEFF", 30: "0xECF4FF", 31: "0xF9FDFF", 32: "0xE6FCFF", 33: "0xF2FFFE", 34: "0xCFFEF0", 35: "0xEAFFEF", 36: "0xE3FBE9", 37: "0xF3F8F4", 38: "0xF1FEED", 39: "0xE7FFDF", 40: "0xF2FFEA", 41: "0xFFFFE3", 42: "0xFCFCE9"}
; /INI --------------------------------------
SendKeysToFix=Enter,Space,Esc,Tab,Home,End,PgUp,PgDn,Up,Down,Left,Right,F1,F2,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,AppsKey
;TerminatingCharacters={Alt}{LWin}{RWin}{Shift}{enter}{space}{esc}{tab}{Home}{End}{PgUp}{PgDn}{Up}{Down}{Left}{Right}{F1}{F2}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}.,¿?¡!'"()[]{}{}}{{}~$&*-+=\/><^|@#:`%; ; "%
TerminatingCharacters={Alt}{LWin}{RWin}{enter}{space}{esc}{tab}{Home}{End}{PgUp}{PgDn}{Up}{Down}{Left}{Right}{F1}{F2}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12} ; "%
CheckTypedLoop:
Gui, 10:Destroy
Loop
{
;Get one key at a time
if (cl_Active = 1) or (ActivateWindow = 1)
{
Gosub, GuiStart
cl_Active:=0, ActivateWindow:=0
}
Input, TypedChar, L1 V I, {BS}%TerminatingCharacters%
CheckTyped(TypedChar,ErrorLevel)
}
Return
; fix 201102 for switching windows with mouse, clear typed stack
~*Lbutton::
Typed=
Return
~*MButton::
Typed=
Return
~*RButton::
Typed=
Return
; Here we build the Search Gui and fill it with content from the bundles and apply settings
GUIStartOmni:
OmniSearch:=1
GuiStart: ; build GUI
If Statistics
Stats("SearchGui")
OmniSearchText:=""
LastText = fadsfSDFDFasdFdfsadfsadFDSFDf
If !WinActive(AppWindow)
GetActiveWindowStats()
Else
Gosub, ToggleView
Gui, 1:Destroy ; just to be sure
Gui, 1:+Border +Resize +MinSize%Width%x%Height%
Gui, 1:Menu, MenuBar
Gui, 1:Add, Picture, x4 y4 w%SearchIconSize% h-1, icons\search.ico ; TODO BIGICONS
Gui, 1:Font, s%SearchFontSize% ; TODO BIGICONS
Gui, 1:Add, Edit, 0x8000 x%SearchBoxX% y%SearchBoxY% w%SearchBoxWidth% h%SearchBoxHeight% -VScroll -HScroll gGetText vCurrText, %CurrText% ; TODO BIGICONS
Gui, 1:Add, Button, x300 y2 w30 h20 0x8000 Default hidden gPaste, OK
Gui, 1:Font ; TODO BIGICONS
; TBSTYLE_FLAT := 0x0800 Required to show separators as bars.
; TBSTYLE_TOOLTIPS := 0x0100 Required to show Tooltips.
Gui, 1:Add, Custom, ClassToolbarWindow32 hwndhToolbar 0x0800 0x0100 0x0008 0x0040 x%barx% y%Yctrl% w550 ; TODO BIGICONS
Gui, 1:Font,s%fontsize%,%font%
Gui, 1:Add, Listview, %ShowGrid% count1000 x2 y%YLView% xLV0x100 hwndHLV vSelItem AltSubmit gClicked h%LVHeight% w%LVWidth% , Paste (Enter)|Paste (Shift+Enter)|Key|Short|Index|Bundle ; TODO BIGICONS
Gui, 1:Add, edit, x0 yp+%LVHeight%+2 -VScroll w%LVWidth% h%PreviewHeight%, preview
Gui, 1:Font, s8, Arial
Gui, 1:Add, StatusBar,,
SB1:=Round(.8*Width)
SB2:=Width-SB1
SB_SetParts(SB1,SB2)
SB_SetIcon("icons\lintalist_bundle.ico",,1)
SB_SetIcon("icons\search.ico",,2)
; Gosub, GetText ; commented v1.9.3
; Initialize Toolbars.
; The variable you choose will be your handle to access the class for your toolbar.
MyToolbar := New Toolbar(hToolbar)
; Set ImageList.
MyToolbar.SetImageList(ILA)
; Add buttons; vertical bars count as buttons when calling them via their ID
MyToolbar.Add("Enabled"
, "EditF7=New Snippet (F7):1"
, "EditF4=Edit Snippet (F4):2"
, "EditF5=Copy Snippet (F5):3"
, "" ; vertical bar
, "PauseScriptButton=Toggle Scripts:4"
, "PauseShortcutButton=Toggle Shortcuts:5"
, "PauseShorthandButton=Toggle Shorthand:6"
, "" ; vertical bar
, "SearchLetterVariations=Letter Variations (alt+v):7"
, "Lock=Lock (alt+l):8"
, "Case=Case Sensitive (alt+c):9"
, "" ; vertical bar
, "Label10=Regular Search (alt+r):10"
, "Label11=Fuzzy Search (alt+z):11"
, "Label12=Regular Expression Search (alt+x):12"
, "Label13=Magic Search (alt+m):13")
; Should the button bar be changed we don't need to update all the
; MyToolbar.ModifyButton calls, we can just update the IDs here.
MyToolbarIDs:={ "NewSnippet" : "1"
, "EditSnippet" : "2"
, "CopySnippet" : "3"
, "ToggleScripts" : "5"
, "ToggleShortcuts" : "6"
, "ToggleShorthand" : "7"
, "ToggleLetterVariations" : "9"
, "ToggleLock" : "10"
, "ToggleCase" : "11"
, "RegularSearch" : "13"
, "FuzzySearch" : "14"
, "RegExSearch" : "15"
, "MagicSearch" : "16"}
; Removes text labels and show them as tooltips.
MyToolbar.SetMaxTextRows(0)
; Set a function to monitor the Toolbar's messages.
WM_COMMAND := 0x111
OnMessage(WM_COMMAND, "TB_Messages")
; Set a function to monitor notifications.
WM_NOTIFY := 0x4E
OnMessage(WM_NOTIFY, "TB_Notify")
Gosub, TB_SetButtonStates
XY:=StayOnMonXY(Width*DPIFactor()+20, Height*DPIFactor()+80, Mouse, MouseAlternative, Center) ; was XY:=StayOnMonXY(Width, Height, 0, 1, 0)
StringSplit, Pos, XY, |
Try
Gui, Show, w%Width% h%Height% x%Pos1% y%Pos2%, %AppWindow%
Catch
Gui, Show, w760 h400, %AppWindow%
If (DisplayBundle > 1)
CLV := New LV_Colors(HLV)
If (JumpSearch=1) ; Send clipboard text to search control
{
JumpSearch=0
GuiControl, 1:, Edit1, %clipboard%
ControlSend, Edit1, {End}, %AppWindow%
Sleep 100 ; added as a fix to avoid duplicate search results, not sure if it helps
Gosub, GetText
UpdateLVColWidth()
}
ControlSend, Edit1, {End}, %AppWindow% ; 20110623
Gosub, GetText ; 20110623
PlaySound(PlaySound,"open")
Return
; Incremental Search, here is where the magic starts, based on 320mph version by Fures, if you know of an even FASTER way let me know ;-)
GetText:
Critical, 50 ; experimental-v1.7
;MsgBox % "y1-----" Snippet[1,1,1] ; debug
StartTime := A_TickCount
ControlGetText, CurrText, Edit1, %AppWindow%
If (CurrText = LastText)
{
Critical, off ; experimental-v1.7
Return
}
CurrLen:=StrLen(CurrText)
; LoadBundle() ; 20121209
If (CurrLen = 0) or (CurrLen =< MinLen)
{
LoadBundle()
UpdateLVColWidth()
LastText = fadsfSDFDFasdFdfsadfsadFDSFDf
Gosub, SetStatusBar
Critical, off ; experimental-v1.7
ShowPreview(PreviewSection)
Return
}
Gui, 1:Default
LV_Delete()
GuiControl,1: , Edit2, %A_Space% ; fix preview if no more snippets e.g. ghosting of last snippet
; setup imagelist and define icons
#Include %A_ScriptDir%\include\ImageList.ahk
If (SubStr(CurrText,1,1) = OmniChar) or (OmniSearch = 1)
{
SearchBundles:=Group
OmniSearchText:=" (All)"
}
Else
{
SearchBundles:=Load
OmniSearchText:=""
}
LastText:=CurrText
ShowPreviewToggle=1
Loop, parse, SearchBundles, CSV
{
If (A_TickCount - StartTime > 150) ; was 250 for <1.6 - experimental-v1.7
ControlGetText, CurrText, Edit1, %AppWindow%
If (CurrText <> LastText)
Goto GetText
Bundle:=A_LoopField
Max:=Snippet[Bundle].MaxIndex()
Loop,% Max ; %
{
SearchText:=LTrim(CurrText,OmniChar)
If SearchLetterVariations and (SearchMethod <> 4)
SearchText:=LetterVariations(SearchText,Case)
match=0
; SearchThis1:=Snippet[Bundle,A_Index,1] ; part '1' (enter)
; SearchThis2:=Snippet[Bundle,A_Index,2] ; part '2' (shift-enter)
; SearchThis3:=Snippet[Bundle,A_Index,4] ; shorthand
SearchThis:=Snippet[Bundle,A_Index,1] " " Snippet[Bundle,A_Index,2] " " Snippet[Bundle,A_Index,4] ; part1, part2, shorthand
If (SearchMethod = 1) ; normal
{
if (SearchLetterVariations = 0)
Search(SearchMethod)
else If (SearchLetterVariations = 1) ; search normal with letter variations making it a RegExMatch search
Search(3) ; RegEx search
}
else
Search(SearchMethod)
If (match > 0) ; we have a match
{
IconVal:=""
If (ShowIcons = 1)
{
IconVal:=SetIcon(Snippet[Bundle,A_Index],Snippet[Bundle,A_Index,5])
}
LV_Add(IconVal,Snippet[Bundle,A_Index,"1v"],Snippet[Bundle,A_Index,"2v"],Snippet[Bundle,A_Index,3],Snippet[Bundle,A_Index,4],Bundle . "_" . A_Index, MenuName_%Bundle%) ; populate listview
If (ShowPreviewToggle = 1) ; do only once to improve speed
{
ShowPreview(PreviewSection)
ShowPreviewToggle=0
}
CurrHits:=LV_GetCount()
SB_SetText(CurrHits "/" . ListTotal OmniSearchText,2) ; update status bar with hits / total
If (CurrHits > MaxRes - 1) ; stop search after Max results (takes to long anyway)
Break
}
}
If (match = 0)
SB_SetText(LV_GetCount() "/" . ListTotal OmniSearchText,2) ; otherwise it won't show zero results
}
If (CurrHits = 1)
{
if (AutoExecuteOne = 1)
Gosub, paste
else if (AutoExecuteOne = 2)
Gosub, shiftenter
}
If (DisplayBundle > 1)
Gosub, ColorList
If (ColumnSort <> "NoSort")
SortResults(ColumnSortOption1,ColumnSortOption2,SortDirection)
Return
Search(mode=1)
{
global
if (Mode = 1) ; normal
{
;If (InStr(SearchThis1,SearchText,Case) > 0) or (InStr(SearchThis2,SearchText,Case) > 0) or (InStr(SearchThis3,SearchText,Case) > 0)
If (InStr(SearchThis,SearchText,Case) > 0)
{
Match++
}
}
else if (Mode = 2) ; fuzzy search as of v1.7 using RegExMatch - could be slower
{
SearchRe:=RegExReplace(SearchText,"imU)([\.\*\?\+\{\}\\^\$\(\)])","\$1") ; we need to escape regex symbols - [] are excluded atm
if InStr(SearchRe,A_Space) ; prepare regular expression to ensure search is done independent on the position of the words
SearchRe:="(?=.*" RegExReplace(Trim(SearchRe," "),"iUms)(.*)\s","$1)(?=.*") ")"
SearchRe:="iUmsS)" SearchRe
If (Case = 1) ; case sensitive, remove i) option
SearchRe := LTrim(SearchRe,"i")
;;ToolTip, % "Case: " case " : SearchRe: " SearchRe ; debug only
; If (RegExMatch(SearchThis1, SearchRe) > 0) or (RegExMatch(SearchThis2, SearchRe) > 0) or (RegExMatch(SearchThis3, SearchRe) > 0)
If (RegExMatch(SearchThis, SearchRe) > 0)
{
Match++
}
}
else if (Mode = 3) ; Regular expression search
{
If (SearchMethod = 1) ; normal
SearchRe:=RegExReplace(SearchText,"imU)([\.\*\?\+\{\}\\^\$\(\)])","\$1") ; we need to escape regex symbols - [] are excluded atm
If (Case = 0) ; case insensitive, add auto i) option
SearchRe := "i)" . SearchText
Else
SearchRe := SearchText
;If (RegExMatch(SearchThis1, SearchRe) > 0) or (RegExMatch(SearchThis2, SearchRe) > 0) or (RegExMatch(SearchThis3, SearchRe) > 0)
If (RegExMatch(SearchThis, SearchRe) > 0)
{
Match++
}
}
else if (Mode = 4) ; Magic search
{
SearchRe:="iUmsS)"
Loop, parse, SearchText
SearchRe .= LetterVariations(A_LoopField,case) ".*"
SearchRe:=RTrim(SearchRe,".*")
If (Case = 1) ; case sensitive, remove i) option
SearchRe := LTrim(SearchRe,"i")
;;ToolTip, % "Case: " case " : SearchRe: " SearchRe ; debug only
;If (RegExMatch(SearchThis1, SearchRe) > 0) or (RegExMatch(SearchThis2, SearchRe) > 0) or (RegExMatch(SearchThis3, SearchRe) > 0)
If (RegExMatch(SearchThis, SearchRe) > 0)
{
Match++
}
}
}
ColorList:
If (LV_GetCount() = 0)
Return
GuiControl, -Redraw, SelItem
Loop, % LV_GetCount()
{
LV_GetText(Paste, A_Index, 5) ; get bundle_index from 5th column which is always hidden
StringSplit, paste, paste, _
CLV.Row(A_Index, lvc[paste1], 0x000000)
}
GuiControl, +Redraw, SelItem
Return
; (Double)click in listview, action defined in INI
Clicked:
; user has right-clicked within the listview control. The variable A_EventInfo contains the focused row number.
If (A_GuiEvent = "RightClick")
{
Menu, edit, show ; this is the same menu as used in the Editor, Menubar (edit)
Return
}
; ignore all other events apart from doubleclick and normal left-click
If A_GuiControlEvent not in DoubleClick,Normal
Return
IfEqual A_GuiControlEvent, Normal
{
ShowPreview(PreviewSection)
If (SingleClickSends = 0) ; if set to 1 in configuration a normal click will act
Return ; the same as a doubleclick (also configurable)
}
If (DoubleClickSends = 1)
Gosub, paste
else if (DoubleClickSends = 2)
{
gosub, shiftenter
}
else if (DoubleClickSends = 3)
{
gosub, ctrlenter
}
else if (DoubleClickSends = 4)
{
gosub, shiftctrlenter
}
else if (DoubleClickSends = 5)
{
gosub, editf4
}
else if (DoubleClickSends = 6)
{
gosub, editf7
}
Return
; We made a selection and now want to paste and process the selected text or run script
Paste:
Gui, 1:Submit, NoHide
ControlFocus, SysListView321, %AppWindow%
SelItem := LV_GetNext()
If (SelItem = 0)
SelItem = 1
LV_GetText(Paste, SelItem, 5) ; get bundle_index from 5th column which is always hidden
Gui, 1:Destroy
CurrText= ; 20110623
if (paste = "") ; there were no search results, this will prevent pasting result from empty Gui, instead it would paste the previous one
Return
; We got here via Shortcut or abbreviation defined in active bundle(s)
ViaShortCut:
StringSplit, paste, paste, _ ; split to bundle / index number
Text1 :=Snippet[Paste1,Paste2,1] ; part 1 (enter, or shortcut, or shorthand)
Text2 :=Snippet[Paste1,Paste2,2] ; part 2 (shift-enter)
Script :=Snippet[Paste1,Paste2,5] ; script (if there is a script, run script instead)
If Statistics and SelItem
{
If !Snippet[Paste1,Paste2,3] and !Snippet[Paste1,Paste2,4] ; no shortcut and no shorthand
Stats(MenuName_%paste1% "__viasearch__no-short-defined")
If Snippet[Paste1,Paste2,4]
{
Stats(MenuName_%paste1% "__viasearch__" Snippet[Paste1,Paste2,4])
}
}
If ((Paste2 <> 1) and (SortByUsage = 1)) ; if it already is the first don't bother moving it to the top...
{
BackupSnippet:=Snippet[Paste1].Delete(Paste2)
Snippet[Paste1].InsertAt(1,BackupSnippet)
BackupSnippet:=""
Snippet[Paste1,"Save"]:="1"
}
If (Text1 = "") and (Text2 = "") and (Script = "")
Return ; nothing to paste or run
If (Script = "") or (ScriptPaused = 1) ; script is empty so we need to paste Text1 or Text2
{
If (InStr(Text1, "[[Clipboard]]") > 0) or (InStr(Text2, "[[Clipboard]]") > 0) ; if we do it here it saves us some time getting back the original clipsaved variable
{ ; insert clipboard
StringReplace, Text1, Text1, [[Clipboard]], %Clipboard%, All
StringReplace, Text2, Text2, [[Clipboard]], %Clipboard%, All
}
If (PastText1 = 1) OR (Text2 = "")
Clip:=Text1
Else If (PastText1 = 0) ; if shift-enter use Text2 BUT if it is empty revert to Text1
{
Clip:=Text2
PastText1 = 1 ; restore default paste
}
If (Text1 = "") and (Text2 <> "") ; if Text1 is empty check if Text2 has content so we can paste that
Clip:=Text2
ClipSet("s",1,SendMethod,Clipboard) ; store in clip1
ClearClipboard()
; process formatted text: HTML, Markdown, RTF and Image
; RTF and Image are processed here, MD and HTML just before pasting to allow for nesting snippets using [[snippet=]]
formatMD:=0,formatHTML:=0
If RegExMatch(Clip,"iU)\[\[(rtf=.*|image=.*)\]\]")
{
WinClip.Clear()
formatted:=1
if InStr(Clip,"[[rtf=")
{
RegExMatch(Clip, "iU)\[\[rtf=([^[]*)\]\]", ClipQ, 1)
FileRead,Clip,%ClipQ1%
Gosub, ProcessText
Gosub, CheckLineFeed
If CancelPlugin
{
If TryClipboard()
Clipboard:=ClipSet("g",1,SendMethod)
ClipSet("ea",1,SendMethod)
Return
}
ClipQ1:=FixURI(ClipQ1,"rtf",A_ScriptDir)
WinClip.SetRTF(Clip)
}
else if InStr(Clip,"[[image=")
{
RegExMatch(Clip, "iU)\[\[Image=([^[]*)\]\]", ClipQ, 1)
If (ClipQ1 = "clipboard")
ClipQ1:=StrReplace(ClipQ1,"clipboard",trim(ClipSet("g",1,SendMethod)," `r`n"))
ClipQ1:=FixURI(ClipQ1,"image",A_ScriptDir)
WinClip.SetBitmap(ClipQ1)
; check if we need to leave image on clipboard after pasting (exception as ProcessText isn't called here)
If InStr(Clip,"[[PasteMethod=1]]")
SnippetPasteMethod:=1
If InStr(Clip,"[[PasteMethod=2]]")
SnippetPasteMethod:=2
}
Clip:="", ClipQ1:="", ClipQ1_ClipboardPath:=""
}
Else
{
Gosub, ProcessText
Gosub, CheckLineFeed
If CancelPlugin
{
If TryClipboard()
Clipboard:=ClipSet("g",1,SendMethod)
ClipSet("ea",1,SendMethod)
Return
}
if (formatMD = 1) or (formatHTML = 1)
{
StringReplace,Clip,Clip,[[md]],,All
StringReplace,Clip,Clip,[[html]],,All
if (formatMD = 1)
Clip:=Markdown2HTML(Clip)
Clip:=FixURI(Clip,"html",A_ScriptDir)
WinClip.SetHTML(Clip)
Clip:=RegExReplace(clip,"iU)</*[^>]*>") ; strip HTML tags so we can paste normal text if need be
WinClip.SetText(Clip)
}
else
{
If TryClipboard()
Clipboard:=ClipSet("s",2,SendMethod,Clip) ; set clip2
}
}
If !(formatted > 0) ; only check for ^| post if it is a plain text snippet
Clipboard:=CheckCursorPos(Clipboard)
formatted:=0
GUI, 1:Destroy
If Statistics
Stats("TotalBytes",StrLen(Clipboard))
If (SnippetPasteMethod = 0) or (SnippetPasteMethod = "") ; there was no PasteMethod plugin in the snippet
{
If (PasteMethod = 0) ; paste it and clear formatted clipboard
{
SendKey(SendMethod, ShortcutPaste)
PlaySound(PlaySound,"paste")
WinClip.Clear()
}
else If (PasteMethod = 1) ; paste it, keep formatted clipboard
{
SendKey(SendMethod, ShortcutPaste)
PlaySound(PlaySound,"paste")
}
}
else ; PasteMethod was set in the snippet
If (SnippetPasteMethod = 1) ; 1 Paste snippet and keep it as the current clipboard content (so you can manually paste it again)
{
SendKey(SendMethod, ShortcutPaste)
PlaySound(PlaySound,"paste")
}
; else PasteMethod was set in the snippet, so it must be: 2 Don't paste snippet content but copy it to the clipboard so you can manually paste it.
If (((BackLeft > 0) or (BackUp > 0)) and (PasteMethod <> 2)) ; place caret at postion defined in snippet text via ^|
{
If (BackUp > 0)
{
SendInput, {Up %BackUp%}{End}
}
SendInput, {Left %BackLeft%}
If PluginMultiCaret
{
Loop, % PluginMultiCaret
{
SendInput, % MultiCaret[ActiveWindowProcessName].key ; TODOMC
Sleep 10
}
SendInput, % MultiCaret[ActiveWindowProcessName].clr ; TODOMC
Sleep 10
PluginMultiCaret=0
}
}
Backleft=0
If (ViaText = 1) ; we came from shorttext
{
ViaText=0
SkipJumpstart=1
}
Text1=
Text2=
Clip=
If (SnippetPasteMethod = 0) or (SnippetPasteMethod = "") ; there was no PasteMethod plugin in the snippet
{
If (PasteMethod = 0) ; it was pasted, restore original clipboard
{
If TryClipboard()
Clipboard:=ClipSet("g",1,SendMethod)
ClipSet("ea",1,SendMethod)
}
else If (PasteMethod = 1) ; it was pasted, clear the original stored clipboard (free memory)
{
ClipSet("ea",1,SendMethod)
}
else If (PasteMethod = 2) ; it wasn't pasted, clear the original stored clipboard (free memory)
{
ClipSet("ea",1,SendMethod)
}
}
else ; PasteMethod was set in the snippet with setting 1 or 2 so don't restore previous clipboard contents but just erase the stored content to save memory
{
ClipSet("ea",1,SendMethod)
}
}
Else If (Script <> "") and (ScriptPaused = 0) ; we run script by saving it to tmp file and running it
{
FileDelete, %TmpDir%\tmpScript.ahk
StringReplace, Script, Script, LLInit(), %LLInit%, All
Loop {
If (InStr(Script, "[[Var=") = 0)
break
RegExMatch(Script, "iU)\[\[Var=([^[]*)\]\]", ClipQ, 1)
StringReplace, Script, Script, [[Var=%ClipQ1%]], % LocalVar_%ClipQ1%, All ; %
}
Loop, 2 ; check for plugins llpart1 and llpart2
{
If InStr(Script,"[[llpart" A_Index "]]")
{
Clip:=Text%A_Index%
Gosub, ProcessText
Gosub, CheckLineFeed
If CancelPlugin
{
If TryClipboard()
Clipboard:=ClipSet("g",1,SendMethod)
ClipSet("ea",1,SendMethod)
Return
}
Clip:=CheckCursorPos(Clip)
; we use (join`n % here to avoid the need to escape the % characters which may be included in the clip variable - https://github.com/lintalist/lintalist/issues/92
StringReplace,Script,Script,[[llpart%A_Index%]],llpart%A_Index%=`n(join``n `%`n%clip%`n)`n`nLLBackLeft%A_Index%:=%BackLeft%`nLLBackUp%A_Index%:=%BackUp%`n`n,All
BackLeft:=0
BackUp:=0
}
}
FileAppend, % Script, %TmpDir%\tmpScript.ahk, UTF-8 ; %
GUI, 1:Destroy
RunWait, %A_AhkPath% "%TmpDir%\tmpScript.ahk"
FileDelete, %TmpDir%\tmpScript.ahk
Script=
If Statistics
Stats("Scripts")
}
If Statistics
Stats(MenuName_%paste1% "__total")
If (OnPaste = 1)
Gosub, SaveSettings
If Statistics and (OmniSearch or OmniSearchText)
Stats("OmniSearch")
OmniSearch:=0,OmniSearchText:="",Typed:="",SnippetPasteMethod:="",SelItem:="" ; ,ViaShorthand:="",ViaText:=""
Return
CheckHitList(CheckHitList, CheckFor, Bundle, RE = 0) ; RE no longer needed?
{
Global load,snippet
HitKeyHistory=
CheckHitList:=CheckHitList "HitList"
Loop, parse, Bundle, CSV
{
CheckBundle:=A_LoopField
If RegExMatch(%CheckHitList%_%CheckBundle%, "imU)" Chr(5) . "\Q" . CheckFor . "\E" . Chr(5)) ; we have a hit so we have to find the snippet ID
{
Loop, % Snippet[CheckBundle].MaxIndex() ; %
{
If (CheckHitList = "HotKeyHitList")
{
If (Snippet[CheckBundle,A_Index,3] ~= "\Q" . CheckFor . "\E") ; use literal search
HitKeyHistory .= CheckBundle . "_" . A_Index ","
}
Else If (CheckHitList = "ShortHandHitList")
{
If (Snippet[CheckBundle,A_Index,4] = CheckFor)
HitKeyHistory .= CheckBundle . "_" . A_Index ","
}
}
}
Index1=
}
Return HitKeyHistory
}
; Sort results - https://github.com/lintalist/lintalist/issues/21
SortResults(SortColumn,SortOption,SortDirection)
{
LV_ModifyCol(SortColumn,SortOption " " SortDirection)
}
; Change with of LV columns depending on content (e.g. autohide if it holds no data)
UpdateLVColWidth()
{
global
local c4w
factor:=225
Col4Correction:=Abs(FontSize-10)*10+10 ; if we set a bigger font size shorthand becomes to narrow very quickly ; TODO BIGICONS/fonts
If DisplayBundle in 0,2 ; Bundle name, 6th column setting 0 & 2 hide column
{
LV_ModifyCol(6,0)
factor:=155
}
else
LV_ModifyCol(6,70)
LV_ModifyCol(5,0) ; hidden Bundle_Index column, always hide
WinGetPos , , , AvailableWidth, , %AppWindow%
If (AvailableWidth = "")
AvailableWidth:=Width
AvailableWidth:=Round(AvailableWidth/DPIFactor())
ColumnWidth:=Round(((AvailableWidth - factor) / 10))
c1w:=Round((ColumnWidth) * (ColumnWidthPart1/10) - (Col4Correction/4) - 15)
c2w:=Round((ColumnWidth) * (ColumnWidthPart2/10) - (Col4Correction/4) - 10)
If (Col3 = 0) ; shortcut column
{