Lintalist 1.9 Searchable interactive lists to copy & paste text with plugins

Post your working scripts, libraries and tools
User avatar
SirSocks
Posts: 183
Joined: 26 Oct 2018, 08:14

Re: Lintalist 1.9 Searchable interactive lists to copy & paste text with plugins

15 Apr 2020, 21:46

Thank you. This seems very handy. I'll give it a try.
list
Posts: 186
Joined: 26 Mar 2014, 14:03
Contact:

Re: Lintalist 1.9 Searchable interactive lists to copy & paste text with plugins

07 May 2020, 12:39

There is now a development branch available that replaces the Loop + Input with the Hotstring() - took me a while to implement.
It should work the same as before (hopefully) - this is a first step, once I'm confident this works as it should (e.g. the same) I can add other hotstring features as well by allowing the user to enter native hotstring features for example (:C:BTW, :*:etc)

https://github.com/lintalist/lintalist/issues/144#issuecomment-625394959

Do backup your bundles, I had a bug at some point that deleted snippets after using a hotstring...
gibbons6546
Posts: 9
Joined: 07 Apr 2020, 11:53

"User-friendly" running text file list for choice plugin

07 May 2020, 19:58

Hello, I would very much appreciate any help regarding this problem I am having with implementing LL to achieve a certain process.

I am trying to have LL modify a text file before LL uses that text file in its "choice" plugin. However, I cannot seem to get this to work. My idea is that I have "Test.txt" being a user-friendly text file in which I can constantly add/edit list items (using line breaks to separate list items), and "Test - Modified.txt" being that same document but formatted for LL's "choice" plugin (i.e., the line breaks are replaced with "|" symbols). I figured the below would be one way to do this, but it is ultimately failing for me. The script generates "Test - Modified.txt" only after the LL choice plugin is run and not before it is run. So the choice plugin ultimately pulls up a blank choice list because Test - Modified.txt does not exist when the choice plugin is run. When I hit enter on that blank choice list, the list closes and only then is "Test - Modified.txt" finally created (but too late for the choice plugin to use).

Any help would be greatly appreciated. Alternatively, if anyone knows of an easier way to achieve a "user-friendly" running text file list, that is ultimately what I am trying to achieve. Thank you very much for any possible help.

The is the Script portion of my snippet:

Code: Select all

#NoEnv
#SingleInstance, force
SetBatchLines, -1
ListLines, off

FileRead, TextVar, C:\Users\Gibbons\Desktop\Test.txt
TextForChoicePlugin := StrReplace(TextVar, "`r`n", "|") ; replaces line breaks with "|" symbols for LL's choice plugin
	
FileLocation = C:\Users\Gibbons\Desktop\Test - Modified.txt
FileDelete, %FileLocation%
FileAppend, %TextForChoicePlugin%, %FileLocation%

[[llpart1]] ; I expected this to cause the Part 1 snippet below to run LL's choice plugin with the list items in "Test - Modified.txt" but it fails to do so.

ExitApp
This is Part 1 of the snippet:

Code: Select all

[[Choice=!|[[File=C:\Users\Gibbons\Desktop\Test - Modified.txt]]]]
list
Posts: 186
Joined: 26 Mar 2014, 14:03
Contact:

Re: Lintalist 1.9 Searchable interactive lists to copy & paste text with plugins

08 May 2020, 13:21

I can see how that would be useful and you would expect something like

Code: Select all

[[Choice=!|[[File=C:\Users\Gibbons\Desktop\Test - Modified.txt]]]]
to work, but it doesn't at the moment. I will think about how to allow it.

But there are some workarounds which you may or may not like.

1 - Using Split + File + Choice

Snippet:

Code: Select all

[[Split=[[File=test.txt]]|\n]][[choice=!|[[sp=1]]|[[sp=2]]|[[sp=3]]|[[sp=4]]|[[sp=5]]|[[sp=6]]|[[sp=7]]|[[sp=8]]|[[sp=9]]|[[sp=10]]|[[sp=11]]|[[sp=12]]|[[sp=13]]|[[sp=14]]|[[sp=15]]|[[sp=16]]|[[sp=17]]|[[sp=18]]|[[sp=19]]|[[sp=20]]|[[sp=21]]|[[sp=22]]|[[sp=23]]|[[sp=24]]|[[sp=25]]|[[sp=26]]|[[sp=27]]|[[sp=28]]|[[sp=29]]|[[sp=30]]|[[sp=31]]|[[sp=32]]|[[sp=33]]|[[sp=34]]|[[sp=35]]|[[sp=36]]|[[sp=37]]|[[sp=38]]|[[sp=39]]|[[sp=40]]|[[sp=41]]|[[sp=42]]|[[sp=43]]|[[sp=44]]|[[sp=45]]|[[sp=46]]|[[sp=47]]|[[sp=48]]|[[sp=49]]|[[sp=50]]|[[sp=51]]|[[sp=52]]|[[sp=53]]|[[sp=54]]|[[sp=55]]|[[sp=56]]|[[sp=57]]|[[sp=58]]|[[sp=59]]|[[sp=60]]|[[sp=61]]|[[sp=62]]|[[sp=63]]|[[sp=64]]|[[sp=65]]|[[sp=66]]|[[sp=67]]|[[sp=68]]|[[sp=69]]|[[sp=70]]|[[sp=71]]|[[sp=72]]|[[sp=73]]|[[sp=74]]|[[sp=75]]|[[sp=76]]|[[sp=77]]|[[sp=78]]|[[sp=79]]|[[sp=80]]|[[sp=81]]|[[sp=82]]|[[sp=83]]|[[sp=84]]|[[sp=85]]|[[sp=86]]|[[sp=87]]|[[sp=88]]|[[sp=89]]|[[sp=90]]|[[sp=91]]|[[sp=92]]|[[sp=93]]|[[sp=94]]|[[sp=95]]|[[sp=96]]|[[sp=97]]|[[sp=98]]|[[sp=99]]|[[sp=100]]]]
This example works for 100 lines as we pass on a 100 SPs to choice. So if your text file is longer or much shorter you can edit the snippet

Drawback: if your text file has 10 lines, there will 90 empty entries in the Choice but as you start typing it filters as it should.

Notes to self:
- update choice to strip empty entries as they are pointless [see edit below]
- perhaps consider a wildcard [[sp=*]], or [[sp=all]] to avoid writing out such a long line of SPs above.

2 - Using many files: File + FileList

Create a folder where you place a number of text files, each one with one or more lines. The filenames will be what you search so they should make sense.

Lintalist-folder\MyFiles\directions to office.txt
Lintalist-folder\MyFiles\bbq recipe.txt
Lintalist-folder\MyFiles\etc.txt

Snippet:

Code: Select all

[[File=[[FileList=!p|MyFiles\*.txt]]]]
You should see choice filled with

Lintalist-folder\MyFiles\directions to office.txt
Lintalist-folder\MyFiles\bbq recipe.txt
Lintalist-folder\MyFiles\etc.txt

Select one and File= should read it and paste it.

Note to self:
- consider a preview option/window for the FileList

3 - using a script

Note you use this in a local var (so place the script and use that as script code, that way you only have to update the script once in case you want to make changes)

Create a new snippet:

Part1 will be

test.txt

Your script:

Code: Select all

/* 
Based on Choice plugins
*/

#NoEnv
#SingleInstance, force
SetBatchLines, -1
ListLines, off
LLInit()                            ; fake call to load global variables from Lintalist main script - see Docs
ClipSet("s",1,SendMethod,Clipboard) ; store current clipboard contents
ClearClipboard()

SetTitleMatchMode, 2

[[llpart1]]

FileRead, PluginOptions, %llpart1%
PluginOptions:=StrReplace(PluginOptions,"`n","|")

Gui, 10:Destroy
Gui, 10:+AlwaysOnTop
Gui, 10:Default
Gui, 10:Add, Edit,     x5 y5 w400 vChoiceFilterText gChoiceFilterText,
Gui, 10:Add, ListBox,  xp yp+30 w400 R10 vItem, %PluginOptions%
Gui, 10:Add, button,   vChoiceCancel gCancelChoice, &Cancel
Gui, 10:Add, button,   xp yp default vChoiceOK gChoiceOK hidden, OK
Gui, 10:Show, w410, Search text file
ControlSend, ListBox1, {Down}, Search text file

Return

ChoiceFilterText:
ControlGetText, PluginsFilterText, Edit1, Search text file
Loop, Parse, PluginOptions, |
	{
	 re:="iUms)" PluginsFilterText
	 if InStr(PluginsFilterText,A_Space) ; prepare regular expression to ensure search is done independent on the position of the words
		re:="iUms)(?=.*" RegExReplace(PluginsFilterText,"iUms)(.*)\s","$1)(?=.*") ")"
	 if RegExMatch(A_LoopField,re) 
		PluginOptionsResults .= A_LoopField "|"
	}
GuiControl, 10:, ListBox1, |%PluginOptionsResults%
PluginsFilterText:=""
PluginOptionsResults:=""
Return

CancelChoice:
Gui, 10:Destroy
ExitApp
Return

ChoiceOK:
Gui, 10:Submit,NoHide
If (item = "") ; if we didn't focus on results list while "typing to filter" in Choice it may return empty
	{
	 ControlGet, item, List, Focused, ListBox1, Search text file
	 If InStr(item,"`n") ; we may get all the results of the "typing to filter" so asume we want first result
		item:=Trim(StrSplit(item,"`n").1,"`n`r")
	}
Gui 10:Destroy
Clipboard:=item
SendKey(SendMethod, ShortcutPaste)  ; paste changed clipboard using SendMethod defined by Lintalist settings
Clipboard:=ClipSet("g",1)           ; restore original clipboard contents
Sleep 500
ExitApp
Return

#IfWinActive, Search text file ahk_class AutoHotkeyGUI
Esc::ExitApp

Up::
SendMessage, 0x188, 0, 0, ListBox1, Search text file  ; 0x188 is LB_GETCURSEL (for a ListBox).
PreviousPos:=ErrorLevel+1
ControlSend, ListBox1, {Up}, Search text file
SendMessage, 0x18b, 0, 0, ListBox1, Search text file  ; 0x18b is LB_GETCOUNT (for a ListBox).
ItemsInList:=ErrorLevel
SendMessage, 0x188, 0, 0, ListBox1, Search text file  ; 0x188 is LB_GETCURSEL (for a ListBox).
ChoicePos:=ErrorLevel+1
If (ChoicePos = PreviousPos)
	{
	SendMessage, 0x18b, 0, 0, ListBox1, Search text file  ; 0x18b is LB_GETCOUNT (for a ListBox).
	SendMessage, 390, (Errorlevel-1), 0, ListBox1, Search text file  ; LB_SETCURSEL = 390
	}
Return

Down::
SendMessage, 0x188, 0, 0, ListBox1, Search text file  ; 0x188 is LB_GETCURSEL (for a ListBox).
PreviousPos:=ErrorLevel+1
SendMessage, 0x18b, 0, 0, ListBox1, Search text file  ; 0x18b is LB_GETCOUNT (for a ListBox).
ItemsInList:=ErrorLevel
ControlSend, ListBox1, {Down}, Search text file
SendMessage, 0x188, 0, 0, ListBox1, Search text file  ; 0x188 is LB_GETCURSEL (for a ListBox).
ChoicePos:=ErrorLevel+1
If (ChoicePos = PreviousPos)
	SendMessage, 390, 0, 0, ListBox1, Search text file  ; LB_SETCURSEL = 390 - position 'one'
Return
#IfWinActive

Edit: if you want to use the 1 split + choice method above but avoid the empty entries insert the following code at https://github.com/lintalist/lintalist/blob/master/plugins/Choice.ahk#L44

Code: Select all

		 PluginOptions:=RegExReplace(PluginOptions,"\|\|*","|",,,2)
- will be part of the next update so nothing is lost
Last edited by list on 09 May 2020, 04:26, edited 2 times in total.
gibbons6546
Posts: 9
Joined: 07 Apr 2020, 11:53

Re: Lintalist 1.9 Searchable interactive lists to copy & paste text with plugins

08 May 2020, 21:09

Hi list,

Thank you for the detailed reply. I think I may have also found an additional solution by creating a new plugin.

I created a plugin called FileChoiceFormat.ahk (based off File.ahk):

Code: Select all

/* 
Plugin        : FileChoiceFormat [based on LL's standard File.ahk plugin]
Purpose       : Convert contents of file to Choice Plugin format, then inserts the contents of that formatted file
Version       : 1.0
*/

GetSnippetFileChoiceFormat:
FileChoiceFormat=  ; clear variable
FileRead, TextVar, %PluginOptions%
TextVar := StrReplace(TextVar, "`r`n", "|") ; replaces each line break in the text with a "|" symbol in order to format the text properly for LL's Choice plugin
PluginOptions = C:\Temp\TextFileFormattedForChoicePlugin.txt
FileDelete, %PluginOptions%
FileAppend, %TextVar%, %PluginOptions%

 	 Loop ; get text from file that has now been formatted properly for LL's Choice plugin
		{
		 If (InStr(Clip, "[[FileChoiceFormat=") = 0) or (A_Index > 100)
			Break
		 If !InStr(PluginOptions,"|")
		 	{
			 PluginOptions:=FixURI(PluginOptions,"txt",A_ScriptDir)
			 FileRead, PluginSnippetFile, %PluginOptions%
		 	}
		 Else ; we have options, process select first if present
			{
			 If (StrSplit(PluginOptions,"|").2 = "select") or (StrSplit(PluginOptions,"|").3 = "select")
				{
				 PluginSelectedDir:=FixURI(StrSplit(PluginOptions,"|").1,"txt",A_ScriptDir)
				 FileSelectFile, PluginSelectedFile, 3 , %PluginSelectedDir%, Select your file to use, *.txt
				 If (ErrorLevel = 0) ; a file has been selected
					FileRead, PluginSnippetFile, %PluginSelectedFile%
				 else
					CancelPlugin:=1	
				}
			 If (StrSplit(PluginOptions,"|").2 = "clean") or (StrSplit(PluginOptions,"|").3 = "clean")
				{
				 PluginOptions:=FixURI(PluginOptions,"txt",A_ScriptDir)
				 FileRead, PluginSnippetFile, %PluginOptions%
				 StringReplace, PluginSnippetFile, PluginSnippetFile, [, %A_Space%, All
				 StringReplace, PluginSnippetFile, PluginSnippetFile, ], %A_Space%, All
				 StringReplace, PluginSnippetFile, PluginSnippetFile, |, %A_Space%, All
				}
			} 

		 StringReplace, clip, clip, %PluginText%, %PluginSnippetFile%, All

		 PluginSelectedDir:=""
		 PluginSnippetFile:=""
		 PluginOptions:=""
		 PluginText:=""
		 ProcessTextString:=""

		}

FileChoiceFormat= ; clear variable
FileDelete, %PluginOptions%

Return
Then Part 1 of my snippet reads the following:

Code: Select all

[[Choice=!|[[FileChoiceFormat=C:\Users\Gibbons\Desktop\UserFriendyTextFileList.txt]]]]
This seems to work properly but do you see anything that should be tightened up code-wise? (I'm quite an amateur)

Also, do you happen to know how I may be able to include my new plugin FileChoiceFormat in the "Plugins" menu list in the LL snippet editor along with the other standard plugins?

Thank you very much for all your help. LL is a wonderful program, jam packed with tonnes of functionality.
list
Posts: 186
Joined: 26 Mar 2014, 14:03
Contact:

Re: Lintalist 1.9 Searchable interactive lists to copy & paste text with plugins

09 May 2020, 02:47

Adding your own plugin is indeed a good idea - this would be the shortened version - note that you can use relative paths as well. Also you don't have to create a new file as that only slows things down - you should be able to use the code below directly.
Snippet would be:

Code: Select all

[[choice=!|[[FileChoiceFormat=test.txt]]]]
FileChoiceFormat.ahk code

Code: Select all

/* 
Plugin        : FileChoiceFormat [based on LL's standard File.ahk plugin]
Purpose       : Convert contents of file to Choice Plugin format, then inserts the contents of that formatted file
Version       : 1.0
*/

GetSnippetFileChoiceFormat:

	 Loop ; get text from file that has now been formatted properly for LL's Choice plugin
		{
		 If (InStr(Clip, "[[FileChoiceFormat=") = 0) or (A_Index > 100)
			Break
		 PluginOptions:=FixURI(PluginOptions,"txt",A_ScriptDir)
		 FileRead, PluginOptions, %PluginOptions%
		 PluginOptions := StrReplace(PluginOptions, "`r`n", "|")
		 StringReplace, clip, clip, %PluginText%, %PluginOptions%, All
		}	

		 PluginOptions:=""
		 PluginText:=""
		 ProcessTextString:=""

FileChoiceFormat= ; clear variable
Return
Adding this to the menu would require hard coding it into Lintalist at the moment, but it is a nice idea and I've prepared some code for the next version which will include a "create my plugins sub-menu" - if you want to add it already (backup lintalist.ahk just to be sure) insert the code below at line https://github.com/lintalist/lintalist/blob/master/lintalist.ahk#L2804 - save and restart lintalist. You should now have a "MyPlugins > Insert [[FileChoiceFormat=]]" submenu

Code: Select all

; create menu for your own plugins
FileRead, MyPluginsFile, %A_ScriptDir%\plugins\MyPlugins.ahk
	{
	 MyPluginsMenu:=0
	 Loop, parse, MyPluginsFile, `n, `r
		{
		 If RegExMatch(A_LoopField,"i)^#include")
			{
			 If !MyPluginsMenu
				MyPluginsMenu:=1
			 Menu, MyPlugins, Add, % "Insert [[" Trim(StrReplace(SubStr(A_LoopField,InStr(A_LoopField,"\",,0,1)+1),".ahk")," `n`t") "=]]", PluginMenuHandler
			}
		}
	 MyPluginsFile:=""
	}

	If MyPluginsMenu
		{
		Menu, Plugins, Add
		Menu, Plugins, Add, &MyPlugins, :MyPlugins
	}
Edit: for good measure I've updated the post earlier with a fix for empty choice entries (see edit)
gibbons6546
Posts: 9
Joined: 07 Apr 2020, 11:53

Re: Lintalist 1.9 Searchable interactive lists to copy & paste text with plugins

09 May 2020, 12:33

Hi list,

Thank you very much for the code refinement as well as the additional MyPluginsMenu code. These solve all issues and add the functionality I was looking to implement with LL.

A new unrelated issue I am experiencing involves the [[MD]] plugin and the insertion of an MD snippet into the bulleted list of a Microsoft Word document. Essentially, the insertion of the MD snippet causes the list in Word to break. Here is an example Part 1 snippet:

Code: Select all

[[md]]MDTextPastedFromLL
So, if I insert the Part 1 snippet "MDTextPastedFromLL" on a bulleted line in a Word document, LL creates a new and non-bulleted line and inserts the Part 1 snippet on this new non-bulleted line rather than the bulleted line where I intended to insert it. Example:
Bulleted list in Word document before MD plugin paste:
  • Bullet1Text
  • Bullet2Text {I want to append the Part 1 snippet immediately after the text "Bullet2Text" and on this same bullet line}
  • Bullet3Text
Bulleted list in Word document after MD plugin paste:

  • Bullet1Text
Bullet2Text MDTextPastedFromLL {the Part 1 snippet has been pasted on a new and non-bulleted line}
  • {now a blank bullet}
  • Bullet3Text

I presume this same issue would occur with a numbered list in Word but I have not confirmed it but can if you'd like.

Thank you for any help that you may be able to provide!
list
Posts: 186
Joined: 26 Mar 2014, 14:03
Contact:

Re: Lintalist 1.9 Searchable interactive lists to copy & paste text with plugins

09 May 2020, 13:24

When you use Markdown, it is translated into HTML first to be able to paste it as "formatted text". So thinking about what markdown would do with a single line: it converts to html, which would make it <p>text you have in your snippet</p> e.g. a paragraph which would indeed add a new bullet - but it is MD actually needed? If you have a normal one line text snippet without new lines it should insert an empty bullet but just append/insert the text.

If you do need some formatting, use [[html]], that way you can be sure the <p>...</p> will be omitted and no empty bullet should appear, so

Code: Select all

[[html]]this is my snippet, with some <b>bold</b> text ...
Should paste correctly in the bullet without adding a new line (it does so in Libreoffice anyway so I'm guessing it does so in Word)
gibbons6546
Posts: 9
Joined: 07 Apr 2020, 11:53

Re: Lintalist 1.9 Searchable interactive lists to copy & paste text with plugins

09 May 2020, 15:14

Hi list. Your suggestion to use html worked perfectly in Microsoft Word. And thank you for the explanation regarding what's happening under the hood with the MD plugin.

I look forward to implementing more of LL in my daily tasks.

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 31 guests