Caret position - Take 2

468 views
Skip to first unread message

Mat

unread,
Jul 5, 2020, 12:12:10 PM7/5/20
to TiddlyWikiDev
Attention Jed, but really anyone who agrees EditorMagic  is a worthwhile concept (i.e to access anything directly as you're typing):

EditorMagic will not work unless someone helps out with to either tweak Jeds "poupup at caret position plugin" or create an alternative implementation, i.e: A plugin that floats a tiddler at caret position in the editor. Below I describe some of the problems with the plugin and what is required for a real use case like EditorMagic. 

I set up Popupissue for this issue and for testing, which is a much scaled down version of EditorMagic, limited to "title picking". Beyond Jeds plugin, Popupissue is basically limited to a single code tiddler (the popup content) and should not be difficult to understand. Briefly; it ensures the edited tiddlers text contains the trigger string [[ and identifies the "fragment", i.e [[this , and lists all tiddler titles with that prefix. Each listed title is really a button and clicking it inserts the [[title]] in the text. 

So, as seen in Popupissue the current plugin is insufficient in these regards:
  • There is no currentTiddler variable accessible in the popup. Thus I'm forced to use "[list[$:/StoryList]prefix[Draft]]" (which is ambiguous). 
  • I would assume this is also why having two tiddlers in edit mode and typing [[t in the top one and [[E in the second one still only shows the popup content for [[t in both.
  • Within a tiddler, it is desirable if the popup differentiates between the fields, i.e currently if the popup shows from typing e.g [[t then if clicking in the title field, the same open popup will move up to there still showing the results for [[t
  • The plugin seems incompatible with TWs Editor Toolbar, i.e the Editor Toolbar must be switched off in the Ctrlpanel settings.

A note: If I understand @Jeds plugin it calculates the caret position relative to the viewports upper left corner. Maybe it would be possible to calculate it relative to the tiddlers corner? ...and maybe this would resolve most of the bulleted issues auotmatically as they are all relative to the tiddler both in terms of position and in terms of currentTiddler reference.

- @Jed, anyone?

Thank you all!


<:-)


-----------------------------------------------------------------------------------------

Reference

Jed Carty

unread,
Jul 6, 2020, 6:30:15 AM7/6/20
to TiddlyWikiDev
It is probably possible to pass the name of the current tiddler when the tiddler is in edit mode and has focus by using css selectors or by walking up the dom tree until you reach a div that has the data-tiddler-title attribute.

This should also be possible in text areas outside of edit mode as long as they are inside a tiddler, I don't know if it would work in places like the sidebar.

The third item in your list (the popup staying open) is a problem with when the values update. At the moment it is only on keyup. That should probably be changed to keydown. Making it also update on focus and blur events would probably help.

The last item, being incompatible with the editor toolbar, is because when the toolbar is active the editor is put in an iframe. There are limits to the information that can be passed in and out of an iframe. We can almost certainly work around this but I didn't work on it.

Saq Imtiaz

unread,
Jul 6, 2020, 10:25:54 AM7/6/20
to TiddlyWikiDev
The approach I would try is:
- extend the edit-text widget engines with a keydown event listener which saves the caret position in a state tiddler specific for that field and tiddler.

- have a reveal widget that gets triggered as a popup, depending on the text in the textarea, using the caret position.

- if the reveal widget is added to the edit template, it will automatically be in the correct context to access variables like currentTiddler and storyTiddler

- Extending the framed engine with an event listener also gives us access to the iframe and makes it easier to calculate the correct position. Snowgoon's plugin takes this approach.

- the core is being patched with code to dismiss popups when clicking in another input field. So using reveal/popup mechanism means that will be helpful as well.

PS: I like the "proof of concept" label in the Site Title, nicely implemented.

Saq Imtiaz

unread,
Jul 7, 2020, 3:18:04 AM7/7/20
to TiddlyWikiDev
@Mat

Play with this and see if it's closer to what you are thinking of:

It's a quick 30 minute hack so expect it to be rough. In particular if you have unfinished links that can cause some issues, and it will only in textareas/inputs where it has been setup to work.

But if it seems useful I can explain the details.


Mat

unread,
Jul 7, 2020, 3:30:55 PM7/7/20
to TiddlyWikiDev
Jed, thank you for replying and following this!

It is probably possible to pass the name of the current tiddler when the tiddler is in edit mode and has focus by using css selectors or by walking up the dom tree until you reach a div that has the data-tiddler-title attribute.

Sounds hopeful. I have no idea how to pass it using css though. I don't know if it is relevant but Tobias made this dom plugin long ago.
 
This should also be possible in text areas outside of edit mode as long as they are inside a tiddler, I don't know if it would work in places like the sidebar.

Maybe the currentTiddler could be stored in a state tiddler, as set when focussing on a tiddler?

The third item in your list (the popup staying open) is a problem with when the values update. At the moment it is only on keyup. That should probably be changed to keydown. Making it also update on focus and blur events would probably help.

A sufficient simplification, at least for now, might be to limit the whole mechanism to only work on the text field?
 
The last item, being incompatible with the editor toolbar, is because when the toolbar is active the editor is put in an iframe. There are limits to the information that can be passed in and out of an iframe. We can almost certainly work around this but I didn't work on it.

Again, hopeful to hear. Overall, much of the editor toolbar functionality would actually be better suited inside EditorMagic but it would probably be a hard sell if it is required. 

But, for now, I think the most important thing is the currentTiddler matter because it prevents the plugin from being used at all outside the demo. If you have a chance to experiment a bit, it would be terrific!

Thanks again!

<:-)

TonyM

unread,
Jul 7, 2020, 6:38:54 PM7/7/20
to TiddlyWikiDev
Mat,

Much of this here is beyond me, however I read your desire to get a focused tiddler value, however made me wonder if I have something that can help.

The last opened, linked to or edited tiddler (draft of), I call this the "focused tiddler", is stored in $:/HistoryList!!current-tiddler

I am now using this to track the last focused tiddler and scroll to return to that tiddler within a long story.

Regards
Tony

TonyM

unread,
Jul 7, 2020, 6:40:57 PM7/7/20
to TiddlyWikiDev
Post Script,

Place this in a tiddler tagged $:/tags/SideBarSegment and move it up in the display order to see how this value changes 

<$tiddler tiddler={{$:/HistoryList!!current-tiddler}} >
{{||$:/core/ui/Buttons/edit}}
<$button to=<
<currentTiddler>> tooltip="Jump to focused Tiddler" actions=focus-tiddler-actions class="tc-btn-invisible tc-tiddlylink">
<small><$text text={{$:/HistoryList!!current-tiddler}}/></small>
</$button>
</$tiddler>

Regards
Tony

Saq Imtiaz

unread,
Jul 8, 2020, 12:59:44 AM7/8/20
to TiddlyWikiDev
@Tony Please consider using a different term instead of "focused tiddler" as this is likely to lead to misunderstandings. Focus has a very specific meaning in HTML parlance, in brief the element with focus is the target for keyboard input.

What the history list keeps track of is not the same thing, it is the last tiddler navigated to via the tm-navigate message. If you have tiddler A open in the story and click a link to tiddler B to open it, tiddler B has focus and has its name set in $:/HistoryList!!current-tiddler. However, if you now click on any part of tiddler A it will receive focus where as the history list is not updated. Similarly if you click some part of the side bar, it now has focus.

Also note that there have already been discussions around the need for extending the TW core to keep track of focus and which tiddler has focus. Unconventional use of the term focus will foster confusion.

Lastly, be aware that the history list isn't always updated when a tiddler is opened. An example is direct manipulation of the storylist via action-setfield or action-listops widgets.

Cheers,
Saq

Eric Shulman

unread,
Jul 8, 2020, 1:46:54 AM7/8/20
to TiddlyWikiDev
On Tuesday, July 7, 2020 at 9:59:44 PM UTC-7, Saq Imtiaz wrote:
Lastly, be aware that the history list isn't always updated when a tiddler is opened. An example is direct manipulation of the storylist via action-setfield or action-listops widgets.

The history list is also NOT updated when a tiddler is *closed*.  Thus, if you navigate to TiddlerA, it will set the value in $:/HistoryList!!current-tiddler, BUT... if you then
close TiddlerA, it will still be set as the value in $:/HistoryList!!current-tiddler.

Working with the $:/HistoryList data can be tricky.   For example, when you first load a TW document, there is *no history list*, even if there are
$:/DefaultTiddlers that are initially displayed.  Similarly, if you use a permaview/permalink URL to open the document, then those tiddlers are also
not in the $:/HistoryList.  However, they ARE in the $:/StoryList

Also note that if you are using "zoomin" mode, only one tiddler will be visible, but the $:/StoryList will still have all tiddlers that were opened and not yet closed.

Thus, you can't always rely on $:/HistoryList!!current-tiddler to tell you which tiddler is the "active tiddler" (aka, what you called the "focused tiddler")

For some interesting bits and pieces, check out: http://tiddlytools.com/InsideTW/#TiddlyTools%2FHistory

If you "unlock" the InsideTW document (padlock icon, upper right of window) and then view the "history" (the clock button in the tiddler's toolbar), you will
see a popup that lists all the tiddlers in the $:/HistoryList.  There's a "double chevron down" button (in the history popup's "titlebar") that will open 
"diagnostics" that shows the contents of the $:/HistoryList, as well as the current $:/StoryList and the "computed history" (combining both those lists,
plus the $:/DefaultTiddlers).

This might give you some ideas on how to deal with $:/HistoryList for your purposes.

-e

Saq Imtiaz

unread,
Jul 8, 2020, 3:22:42 AM7/8/20
to TiddlyWikiDev
Hiya Mat,

Checking to see if you saw the demo I posted for you?

You may or may not like the implementation approach, but I think it addresses most of your concerns and potentially has ideas that might be beneficial in whichever implementation you decide to pursue.

You get full access to variables like currentTiddler; there are improvements that let you know exactly where the text caret is, so you can ignore text before or after, and I tweaked your popup code so that it doesn't give multiple results if there are multiple unclosed link brackets .... amongst other things. 

Still lots more room for improvement, like only showing a popup if the triggers are found, rather than showing an empty popup (not visible) if there are no trigger matches.

Cheers,
Saq

Jed Carty

unread,
Jul 8, 2020, 8:30:28 AM7/8/20
to TiddlyWikiDev
Mat,

Walking up the Dom tree would just be examining each ancestor of the input element in order until you find one with a data-tiddler-title attribute and use that to find the tiddler that contains the input you are currently using. You may be able to somehow do the same thing with css selectors but I am not good enough with css to say. Either way it would have to be on the javascript side of things. Storing this in a state tiddler would be simple enough, it already stores the caret position so adding in the current tiddler when one exists and can be found would make sense. I don't think finding the current tiddler for inputs on the sidebar can be done the same way, but adding in specific exceptions, like for the search input, should be doable.

Unfortunately limiting it to just the text field requires examining the dom tree to determine if the current input element is part of a tiddler text field or not, so that may actually increase the complexity. I think going directly to making it work with every input element is the way to go.

Any buttons that you include that have the same function as the editor toolbar will have the same limitations unless someone comes up with some new magic. The edit area is in an iframe because an iframe can keep its input element that currently has focus when you click outside the iframe, but only one UI element can have focus in the same frame. So the text field loses focus when you click on one of the buttons in the edit toolbar unless the text field is split into a separate iframe. Losing focus means the caret position is lost so inserting text at the caret position doesn't work because the caret is not in the text filed when you click the button.

There is a mechanism for passing information from an iframe to the containing page, it is what we use for the plugin library and twederation. There must be someway the iframe lets the wiki know which tiddler it is editing, so we can get that information to set the current tiddler when the toolbar is in use.

TonyM

unread,
Jul 8, 2020, 8:49:24 AM7/8/20
to TiddlyWikiDev
Saq et all

Not wishing to be too off topic.

Perhaps focus is not the name but I have made a solution from this idea, that works well. I would love any suggestions what to call it. Last navigated to tiddler is a mouthful.

As in my first reply;

The last opened, linked to or edited tiddler (draft of),

In addition I have an icon on any tiddler indicating if it has "focus" and if not to make it so.

I also have a list of history tiddlers in a side bar that only shows drafts if in edit, and my recently visited tiddlers ie history as well as edit and open in new window buttons.

From a designer perspective this is a very efficient way to work on a large number of tiddlers.

Without too much detail it is superior to other ways of juggling a lot of tiddlers.

Back to the OT it would be nice if jumping from one edit tiddler to another the cursor position was retained and restored especially when you go elsewhere to obtain content to insert. Is this restoring the carpet position and could it be saved in the history entries.

Regards
Tony

Saq Imtiaz

unread,
Jul 8, 2020, 9:03:39 AM7/8/20
to TiddlyWikiDev
@Tony: Eric's suggestion of "active tiddler" is probably a good stop-gap solution as it doesn't clash with established nomenclature. Suggest you use that name (active tiddler) to post a demo of what you are talking about in a new thread if you want feedback and/or suggestions for a better name.

Mat

unread,
Jul 8, 2020, 3:11:52 PM7/8/20
to TiddlyWikiDev
@Saq - as noted previously; thank you for your support!

https://saqimtiaz.github.io/sq-tw/editormagic-poc.html 
You get full access to variables like currentTiddler; there are improvements that let you know exactly where the text caret is, so you can ignore text before or after, and I tweaked your popup code so that it doesn't give multiple results if there are multiple unclosed link brackets .... amongst other things. 
How anyone can throw together that in 30 minutes is astonishing, to say the least. And you've immediately grasped some of the big struggles I've had/have. 


[...] if you have unfinished links that can cause some issues, and it will only in textareas/inputs where it has been setup to work.

Do you refer to what I see in you $:/core/modules/widgets/action-popupcaret - i.e the reference to Snowgoons cursor-position.js ? If yes, I'm assuming this is why the default text editor is changed. Does this mean the solution cannot work with the regular text editor? I'm hoping EditorMagic can eventually become a plugin that people can rely on and not cause problem in core updates.


Still lots more room for improvement, like only showing a popup if the triggers are found, rather than showing an empty popup (not visible) if there are no trigger matches.

You're absolutely right but if I have any forte it would be css - or, rather, patience with css - so that's the only way I figured out how to control show or not without js. If you have better solutions, I'd be more than happy to see them ;-)

Actually -  I have no idea what to do next in this, mostly because of limits in what wikitext can do since I don't know JS. A long time ago I posted gh request for popups via custom strings exactly because it is beyond wikitext, and because I think such a mechanism would enable a lot of things for wikitext coders i.e to focus on the popup content. From your demo, you seem to have created a solution for this so do you think you could generalize it into a plugin? For one thing, I note that you announced a floating editor toolbar - well done!!! - which seems to also use a popup mechanism so it is clear that there are use cases.

Sorry if I'm a bit incoherent. EditorMagic, or something like it, still doesn't exist but I have no idea what I can do as a next step.

<:-)

Saq Imtiaz

unread,
Jul 8, 2020, 4:02:57 PM7/8/20
to TiddlyWikiDev
Hi Mat,

It helps that I made a PR for snowgoon's plugin a few weeks ago to make a few improvements and optimizations, so I understand both his code and some of the challenges involved with popups in textareas. I didn't have more time or I would have cleaned it up before sharing.

If you are interested in pursuing my approach further with wikitext, I think that is possible in the sense that the issues you mentioned in your original post should be resolved, though I can't say what else may come up later down the road. Only one way to find out though!

I will explain to you how my demo works, and if after reading you want to work with it further (with wikitext), I'll clean it up and provide you with a stripped down bare minimum setup to work with.

Firstly, I would strongly advise you not to worry about this bit for now: "I'm hoping EditorMagic can eventually become a plugin that people can rely on and not cause problem in core updates."

Get the functionality you want working for now, even if it means overwriting a shadow tiddler or two. Once everything is in place, it should be possible to find a way to refactor the code to avoid these issues. Either by finding a different way to insert the extra bits we need into templates, or a pull request for a core change. But if you get hung up on this part now, you don't actually have anything to show to justify any changes.... hello vicious cycle. I already have ideas for how the shadow tiddler editing problems could be worked around later once the rest of the puzzle is in place.

OK, about my demo. I favour a more TiddlyWiki approach, which to me means using as much of core features as possible and introducing a new custom widget or two to get any missing functionality that we need. 

Requirements:
  • the ability for edit-text widget to fire actions on input, taken from this PR (https://github.com/Jermolene/TiddlyWiki5/pull/4725) No reason to hesitate to use this. The actions part of it can even be made a separate PR to get it merged sooner, or be packaged as a tiny plugin until it is merged.

  • $:/plugins/snowgoon88/edit-comptext/cursor-position.js from snowgoon, just this tiddler not the entire plugin.

  • the latest pre-release. It contains an already merged patch for the edit widget that is needed.

  • action-popupcaret widget - introduced by me. When fired it triggers a popup at the caret position. It needs to be fired by the edit widget, so that it knows which textarea to work with, and so that it inherits variables like currentTiddler. Note this refers to a standard core popup, i.e. a Reveal Widget.

    This action widget also sets a field in the state tiddler for the popup, telling us the position of the caret. This is the position in characters from the start of the text. We can access this in the popup.

  • The default text-editor has not been changed. (CodeMirror is installed just for convenience during development, it is not a requirement). The shadow tiddler $:/core/ui/EditTemplate/body/editor has been changed to add actions to the edit widget, and add the reveal widget for the popup we want to show. This reveal widget contains a few lines of wikitext which transclude your EditorMagic popup tiddler. 

  • The rest of the logic for what to show in the popup is still all wiki text based and mostly your original wikitext.
Flow
  • User typing in textarea triggers action-popupcaret widget
  • Popup is created at caret position
  • What happens inside the popup is up to you and based entirely on wikitext.
    You do have access to the caret position, this is the position in characters from the start of the text.
Changes to the wikitext inside the popup
  • Since we have access to the caret position, I split the tiddler text at the caret position, discarding everything after the caret. This makes it very easy to know where our string ends.
  • I changed the logic a bit so that in case there are multiple unclosed [[ brackets, we only consider the last one before the caret.
  • There was a bug in your code where autocompleting [[tid to [[tidone]] would also mangle already existing links that matched [[tid. I changed the logic for the text replacement so we take everything before the trigger, plus the link + everything after the caret and join them together. All of this is easy since we have the caret position.
  • Your code also wasn't matching if the typed part of the tiddler title contained spaces, that should be fixed too.
If you want to work with this, I can clean it up. Then you can go crazy with wikitext in EditorMagic/_Popup

 My advice would be to try and get it to a working title autocomplete solution. We should be very close already. That will help iron out any kinks in the popup display logic etc. Then once that is working well, you can use that as a foundation to try and implement other EditorMagic functionality.

Still lots more room for improvement, like only showing a popup if the triggers are found, rather than showing an empty popup (not visible) if there are no trigger matches.

This can be done via wikitext as well by just moving around some of your wikitext from the popup tiddler. But its an incremental improvement that can be done later, and no need to get into it now.

In conclusion:
While there may be some rough edges, I think this provides the basis for reliably triggering a popup (reveal widget) at the caret position in both core editors, the simple one and the framed one (with toolbar), in response to a user typing.

Cheers,
Saq

Mat

unread,
Jul 8, 2020, 7:48:56 PM7/8/20
to TiddlyWikiDev
Saq Imtiaz wrote:
 
If you want to work with this, I can clean it up. Then you can go crazy with wikitext in EditorMagic/_Popup

YES, PLEASE! and that's an understatement ;-)

It is actually really stressful to hit the "JS wall" when pushing the limits of wikitext, and especially that I can't really make any PRs. So thank you for the calming explanation of your dev process and attitude.

Can I ask, is @Jeds construct of use? It obviously has been very useful for my demos, and I also recall Snowgoon bringing up some strenghts with it that his solution didn't have. Or maybe your approach covers things fully anyway? The use of caret position by character count does seem advantageous especially for the subsequent text manipulation. BTW, I'm assuming your "floating editor toolbar" also keeps track of start-stop position of the selected text.

  • the ability for edit-text widget to fire actions on input, taken from this PR (https://github.com/Jermolene/TiddlyWiki5/pull/4725) No reason to hesitate to use this. The actions part of it can even be made a separate PR to get it merged sooner, or be packaged as a tiny plugin until it is merged.
It does sound sensible with a separate primitive to fire actions from it. Would that be an actions attribute, as exists in a few other widgets?
 
  • action-popupcaret widget  [...]  Reveal Widget.
Excellent! 

  • [...] also sets a field in the state tiddler for the popup, telling us the position of the caret. This is the position in characters from the start of the text. We can access this in the popup.
:-D Is this number updated by each key stroke as you type? Just curious.


In conclusion:
While there may be [...]

My conclusion is more like: Hoorayyyy!!!

 <:-)

Saq Imtiaz

unread,
Jul 9, 2020, 3:19:24 AM7/9/20
to TiddlyWikiDev
Hi Mat,

Let's hope I haven't been too bold and jinxed us, and that we wont find some killer bug in my approach ;)



Can I ask, is @Jeds construct of use? It obviously has been very useful for my demos, and I also recall Snowgoon bringing up some strenghts with it that his solution didn't have. Or maybe your approach covers things fully anyway?

I think my approach covers the strengths Snowgoon alluded to, while also not being a global approach which as he mentioned my not be needed. I think the major limitation of my approach is that the action-popupcaret widget has to be fired by the edit widget, to know which text area to work, get the position of the iframe correctly etc. However since the idea of a caret position is specific to input/textareas I don't see this as a real issue. I am not familiar with the details of Jed's approach, so if you feel we are loosing something useful do point it out.
 
The use of caret position by character count does seem advantageous especially for the subsequent text manipulation. BTW, I'm assuming your "floating editor toolbar" also keeps track of start-stop position of the selected text.

Yes. That was a super quick hack while on the phone, combining techniques from my work with Snowgoon's plugin, some tweaks in Streams to do with dividing text at the caret position, work on your demo, and a request for a more slimmed down editor toolbar in Streams.

It also keeps track of the selected text, the tiddler text before the selected text, and after the selected text. All updated on each keystroke.
 
  • the ability for edit-text widget to fire actions on input, taken from this PR (https://github.com/Jermolene/TiddlyWiki5/pull/4725) No reason to hesitate to use this. The actions part of it can even be made a separate PR to get it merged sooner, or be packaged as a tiny plugin until it is merged.
It does sound sensible with a separate primitive to fire actions from it. Would that be an actions attribute, as exists in a few other widgets?

Currently it is inputActions, to differentiate from actions attributes on other widgets that are fired on click, whereas these fire when there is input into the textarea.
  • [...] also sets a field in the state tiddler for the popup, telling us the position of the caret. This is the position in characters from the start of the text. We can access this in the popup.
:-D Is this number updated by each key stroke as you type? Just curious.

Yes. Though annoyingly the core handling of the reveal widget doesn't update the position of an already open popup when its state tiddler is updated. I suspect this is an oversight, and anyway it isn't a deal breaker for now. Once we better understand if it would be useful, and what the impact on other things would be, I may open a PR for this.

I'll get a cleaned up demo for you soon, hopefully today.
Cheers,

Saq

Saq Imtiaz

unread,
Jul 9, 2020, 3:25:05 AM7/9/20
to TiddlyWikiDev
@Mat two more things.

Firstly, I haven't thought about adding keyboard navigation support yet, i.e. how to allow a user to choose an autocompleted title using just the keyboard. So that's one challenge still lying ahead.

Secondly: If we move the reveal for the popup in $:/core/ui/EditTemplate/body/editor, inside of the closing </$edit> tag, it would allow editor toolbar commands to work when included in the popup. Nice bonus. 

Furthermore, it would mean that any commands you add in the popup can also make use of https://tiddlywiki.com/#WidgetMessage%3A%20tm-edit-text-operation

We could also extend tm-edit-text to support "replace at caret position" to make the insertion of completed strings easier.

Saq Imtiaz

unread,
Jul 9, 2020, 5:41:48 AM7/9/20
to TiddlyWikiDev
@Mat: https://saqimtiaz.github.io/sq-tw/editormagic-popup.html

All tiddlers needed for the functionality are tagged $:/EditorMagic

The screenshot below (at the very end) shows which fields are set in the state tiddler for the popup. Note that when there is no selection, selection-end = selection-start = caret position (in characters).

When there is no selection, pre-selection is the same as pre-caret, post-selection is the same as post-caret.

Have a look at how in the EditTemplate/Body/Editor (towards the end, just before the translusion of your popup tiddler), we access a field from the state tiddler to set a variable (selectionEnd) for the popup to be able to use. You can set other fields as variables here if you need them. 

<$set name="selectionEnd" filter="[<editorMagicState>get[selection-end]]" select="0"> 
{{||EditorMagic/_Popup}}
</$set>


screenshot:


Mat

unread,
Jul 9, 2020, 11:47:42 AM7/9/20
to TiddlyWikiDev

I haven't thought about adding keyboard navigation support yet,

That feels totally secondary but if it definitely makes sense for any "pick list".
 
Secondly: If we move the reveal for the popup in $:/core/ui/EditTemplate/body/editor, inside of the closing </$edit> tag, it would allow editor toolbar commands to work when included in the popup. Nice bonus. 

</$edit ToHere?> huh?  Is that some super trick or is it an established practice? Regardless, having "editor toolbar commands to work when included in a popup" definitely sounds desirable. I didn't think much about it yet but I'd assume there are tools still more appropriately positioned in the editor toolbar. (On the other hand, it is currently cluttered)

Furthermore, it would mean that any commands you add in the popup can also make use of https://tiddlywiki.com/#WidgetMessage%3A%20tm-edit-text-operation

That's a big deal.
 
We could also extend tm-edit-text to support "replace at caret position" to make the insertion of completed strings easier.

Yes, very reasonable. I take it that the already existing "replace-selection" thus requires a selection of length>0.


@Mat: https://saqimtiaz.github.io/sq-tw/editormagic-popup.html

You've done a fantastic job... in fact, so much so that I'm a bit at loss of what to do next so I'd better ask before going in the wrong direction: Does it already now make sense that I modify the EditorMagic/_Popup to split out the specific title picking functionality to make the EditorMagic/_Popup tiddler general and to make the other popup content functionality tiddlers?

Thank you Saq!

<:-)

Saq Imtiaz

unread,
Jul 9, 2020, 12:44:23 PM7/9/20
to TiddlyWikiDev
Hi Mat,

 
Secondly: If we move the reveal for the popup in $:/core/ui/EditTemplate/body/editor, inside of the closing </$edit> tag, it would allow editor toolbar commands to work when included in the popup. Nice bonus. 

</$edit ToHere?> huh?  Is that some super trick or is it an established practice?

Toolbar buttons use the tm-edit-text-operation message, which is handled by the edit-text widget. Just like most of the messages like tm-navigate etc are handled by a surrounding navigator widget.

 So wherever the tm-edit-text-operation message is sent from, there needs to be an edit widget around it to catch the message and manipulate the text. This is why if you look at $:/core/ui/EditTemplate/body/editor, all the editor toolbar buttons are between <$edit> and </$edit>

The downside to moving the popup reveal inside the edit widget is that the buttons inside popup will only work with the toolbar version of the editor (called the framed editor), if we are using the tm-edit-text-operation message. However, its easy to get a framed editor that doesn't have a visible toolbar and therefore looks just like the simple non-toolbar editor. So I don't see this as a problem. For example in streams whether you choose to have a toolbar or not, it is always the framed toolbar, just sometimes with the toolbar hidden via CSS.

We could also extend tm-edit-text to support "replace at caret position" to make the insertion of completed strings easier.

Yes, very reasonable. I take it that the already existing "replace-selection" thus requires a selection of length>0.


It works without a selection but wouldn't do what you need. It replaces the selected text with a given text. If Hel is selected it can be replaced with HelloThere. With no selection, it would replace nothing with HelloThere and you would get HelHelloThere. So we would need to extend it to replace the non-selected trigger value, just preceding the caret position, with the complete string. It's a nice improvement and would make writing the rest of the functionality with wikitext easier.
 

@Mat: https://saqimtiaz.github.io/sq-tw/editormagic-popup.html

You've done a fantastic job... in fact, so much so that I'm a bit at loss of what to do next so I'd better ask before going in the wrong direction: Does it already now make sense that I modify the EditorMagic/_Popup to split out the specific title picking functionality to make the EditorMagic/_Popup tiddler general and to make the other popup content functionality tiddlers?


My suggestion is to first test this demo robustly. Try different lengths of tiddler, editing at the beginning, end and middle. Identify any bugs or quirks, there will be some. Those will be easier to fix now before we add more complexity.

After that your proposed path sounds good, to split out the title functionality and try to make the popup tiddler more general purpose.

Cheers,
Saq

Mat

unread,
Jul 9, 2020, 1:13:46 PM7/9/20
to TiddlyWikiDev
 between <$edit> and </$edit>

Aha, thanks. The docs explicitly states "The content of the <$edit-text> widget is ignored." but maybe this refers to something else. 

My suggestion is to first test this demo robustly.

Gotcha. I'll pass it through hell.

<:-)

Saq Imtiaz

unread,
Jul 9, 2020, 1:27:48 PM7/9/20
to tiddly...@googlegroups.com
I also recommend to look through the wikitext changes in the popup Tiddler, so you understand what changes were made and why.

--
You received this message because you are subscribed to a topic in the Google Groups "TiddlyWikiDev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/tiddlywikidev/hOlWpnejqvI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to tiddlywikide...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/tiddlywikidev/bb996f37-932c-4bef-831c-1413f1ba6415o%40googlegroups.com.

TonyM

unread,
Jul 9, 2020, 8:18:52 PM7/9/20
to TiddlyWikiDev
Mat and Saq,

I love where this is going and the design principals of generalisation. This sound like a future core component or plugin, if not a configurable one.

I stand ready for testing or any other way I can help, including harvesting content for the insertions. Just give me sufficient instruction. I may use this to add to the tiddlywiki.com doco as well.

On various fronts I have seen the usability of tiddlywiki accelerate of late, with my own library of designs and work around I will be publishing more soon, however tools such as editor magic (my active Tiddler) and more will make design far faster. 

Regards
TW Tones


On Friday, July 10, 2020 at 3:27:48 AM UTC+10, Saq Imtiaz wrote:
I also recommend to look through the wikitext changes in the popup Tiddler, so you understand what changes were made and why.

On Thu, 9 Jul 2020, 19:13 Mat, <matia...@gmail.com> wrote:
 between <$edit> and </$edit>

Aha, thanks. The docs explicitly states "The content of the <$edit-text> widget is ignored." but maybe this refers to something else. 

My suggestion is to first test this demo robustly.

Gotcha. I'll pass it through hell.

<:-)

--
You received this message because you are subscribed to a topic in the Google Groups "TiddlyWikiDev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/tiddlywikidev/hOlWpnejqvI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to tiddly...@googlegroups.com.

Mat

unread,
Jul 10, 2020, 6:01:23 AM7/10/20
to TiddlyWikiDev
Testing the demo:

I find it surprisingly robust but it is also tricky to come up with varied tests, even if I did perform quite a few by now. Here are some findings so far:
  1. Pop up position: Creating a new row seems to take presedence and steer where the popups shows. I get this bug(?) to most consistently show if the text starts out with empty rows, then the popup shows in that area rather than where the title is completed.
  2. I can't find it in this thread now but I think you mentioned that: The popup doesn't follow the caret if it is moved using the keyboard arrows and then typing.
  3. If the text already has the closing brackets, e.g [[bar]] and you stand just to the right of the "r" and pick e.g title "barbaz", then you get [[barbaz]]]] - i.e if there's a closing "]]" they should probably be removed at injection.
  4. Possibly not relevant at this moment: After the injection, it is desirable that focus - i.e the caret - is returned to where the text was just inserted. Currently one has to click to insert caret.
Other tests like inserting normally problematic characters or repeated incomplete strings or using titles of existing tiddlers that have erroneous characters in them seem to work well. 

Are there any ready built "test tiddlers" with typically problematic text or faulty fields, including faulty titles, that people use when testing these things? Or maybe each case is so different that its not worth having such things.

<:-)

Saq Imtiaz

unread,
Jul 10, 2020, 6:25:04 AM7/10/20
to tiddly...@googlegroups.com
Hi Mat,

  1. Pop up position: Creating a new row seems to take presedence and steer where the popups shows. I get this bug(?) to most consistently show if the text starts out with empty rows, then the popup shows in that area rather than where the title is completed.
Could you post a screenshot and/or precise steps to recreate this? I am not quite sure I follow. I wonder if its related to the item below, popup position not updating once it has been shown.
  1. I can't find it in this thread now but I think you mentioned that: The popup doesn't follow the caret if it is moved using the keyboard arrows and then typing.
Yes. Basically under the covers, the first popup is never dismissed until and unless you click somewhere, and when it's shown again, the old position is used because of the way the core handles popups. We could try to patch this now, but I think there is a better way to control triggering the popup which would also handle this issue. So I suggest we live this for now if it's not a deal breaker.

If you don't first trigger a popup and without autocompleting a title, move the caret around with the keyboard, the position should be correct.

Try this:
Open the tiddler $:/plugins/EditorMagic/reveal-widget-tweak and give it a module-type field with value startup. Restart and test again. This is one approach to address the above issue but has other side effects I don't like (which could also be fixed)... anyway there are lots of ways to solve this problem. I think waiting a bit to see how everything else develops will let us choose the best one.

  1. If the text already has the closing brackets, e.g [[bar]] and you stand just to the right of the "r" and pick e.g title "barbaz", then you get [[barbaz]]]] - i.e if there's a closing "]]" they should probably be removed at injection.

Yeah I noticed this too. To be honest, I have experienced similar behaviours in other text editors that do similar things, so I feel like it isn't a huge problem. Autocompleting a link vs updating an existing link are after all different things. 

That said, this is all handled in wikitext. So you could check the portion of the text after the caret, to make sure it doesn't start with the end part of the trigger. If it does, remove those characters.

 But how do you make sure that isn't somehow useful user text you are stripping out? :) 
  1. Possibly not relevant at this moment: After the injection, it is desirable that focus - i.e the caret - is returned to where the text was just inserted. Currently one has to click to insert caret.
I think using the tm-edit-text-operation approach we could address this.  The core otherwise doesn't have any facilities for remembering/restoring the caret position.

Cheers,
Saq
 

Mat

unread,
Jul 11, 2020, 8:03:38 AM7/11/20
to TiddlyWikiDev
The popup position bug: Happily(?) I can't get it to happen again. (It did happen repeatedly previously, also after reloads of page... :-/ ?) Should it somehow occur again I'll shout out but I agree with waiting to see how things develop. And I also cannot find any additional problems - long text, short text, typically problematic characters, multiple unfinished titles, nested titles, draft titles, various story views, various tiddler saving variants, drafts in list, deleting tids as they appear in the list, 

...except for if there's a tiddler titled literally: 

A [[Tiddler

...and I try to complete by typing this

[[A [[Tid

- this gives no popup. My spontaneous feeling is that TWs native warnings against using brackets in titles should be enough to prevent this ...but maybe there are programmatic cases where the user isn't aware that such a string is constructed and the popup functionality doesn't work? Or could there be side effects where links are constructed where there should be none... kind of like accidently inserting an extra markup character which often reverses the markup to the rest of the text rather than the selected portion? Considering that the whole popup is merely a "sugary end-UI" thing, i.e no(?) other functionality will futher depend on the output from it, I think we can disregard this fringe case. And presumably the following ones because the following does work:

[[A [[Tid [[Edito

...i.e this skips over the problems and the popup shows (only) the content: EditorMagic/_Popup

 
So, based on your other feedback on my findings, which I also agree with, I think I'm about ready to actually split out the title functionality and try to make the popup general. I'm starting with this now :-D

<:-)

Saq Imtiaz

unread,
Jul 11, 2020, 8:40:53 AM7/11/20
to TiddlyWikiDev
Hi Mat,

...except for if there's a tiddler titled literally: 

A [[Tiddler

...and I try to complete by typing this

[[A [[Tid

- this gives no popup. My spontaneous feeling is that TWs native warnings against using brackets in titles should be enough to prevent this ...

That is where I would land on this as well.
 
I think we can disregard this fringe case. And presumably the following ones because the following does work:

[[A [[Tid [[Edito

Yes, we use the last match of the trigger before the caret, since that is where the user is typing.
 
So, based on your other feedback on my findings, which I also agree with, I think I'm about ready to actually split out the title functionality and try to make the popup general. I'm starting with this now :-D

Good luck! I'm impressed at how much you've managed to get done with wikitext.

Cheers,
Saq

Saq Imtiaz

unread,
Jul 11, 2020, 10:07:20 AM7/11/20
to TiddlyWikiDev
Mat: decided to make your life a bit harder. There are updates!
https://saqimtiaz.github.io/sq-tw/editormagic-popup.html
  • $:/plugins/EditorMagic/styles (new)
  • $:/plugins/EditorMagic/editor-operations/insert-completion.js (new)
  • $:/core/ui/EditTemplate/body/editor (updated)
  • EditorMagic/_Popup (updated)
The first 3 you can just import as is. They shouldn't cause any problems even if you don't immediately merge the last one.

EditorMagic/_Popup, all changes are just inside the code the button (for the completed link). So you can copy that part.

 <$list filter="""[all[tiddlers]prefix<fragment>]""" variable=name>
 <$button class="tc-btn-invisible tc-tiddlylink">
 <$text text=<<name>>/>
 <$action-sendmessage
 $message="tm-edit-text-operation"
 $param="insert-completion"
 text={{{[
<name>addsuffix<trigger-end>]}}}
 precursor=<
<fragment>
>
 />

 </$button>
 <br>
 </$list>

Note the message with the new $param insert-completion.

Example:
completing [[$:/th to [[$:/themes]]
the parameters to the message should be:
text: $:themes]]   i.e. fragment + trigger-end
precursor: $:/th   i.e. fragment

This should make the insertion of the completed text, easier, more efficient as well as place caret at the correct place.

Cheers,
Saq

Mat

unread,
Jul 11, 2020, 10:47:41 AM7/11/20
to TiddlyWikiDev
@Saq - excellent! The things I did manipulate so far should not be a problem to transfer. Much appreciated. Thank you for fiddling with this. I have a good feeling it will turn into a really useful thingy.

<:-)

Mat

unread,
Jul 11, 2020, 11:10:17 AM7/11/20
to TiddlyWikiDev
[...] as well as place caret at the correct place.

Oooooh yes! 

...

I now did rediscover how to produce the previously mentioned popup position issue:

Type e.g [[Ed to get the popup.
Now type either of:
 - a blank space and several other words
 - or hit the Enter key a few times to get new rows
This hides the popup.
Now, where you're standing, type [[E
This shows the popup in the old place

For example, literally typing this into the editor will show the problem:

If you type '[[Ed' you will get a popup. If you click the title it will show [[EditorMagic/_Popup]].

Now, I don't feel this issue is worth bothering with. The critical part is that when one clicks/picks the title, it is inserted where the caret is not the "old" place. Can you think of why it would be worth bothering with?

<:-)


Mat

unread,
Jul 11, 2020, 12:19:03 PM7/11/20
to TiddlyWikiDev
@Saq, I just realized a thing that I hope to ensure will work also when now building on your mods:

The trigger-end for, specifically, title picking is simple; it is just ]]

But there are many other cases where there are multiple trigger-ends. For example <$widget could end with </$widget> or /> or one might consider merely > to be the end (i.e to close the widget opening tag and then treat the closing tag separately). In my demo it is handled by allowing the trigger-end field to be treated like a list, e.g

trigger-end: /> </$widget>

and the regexpification of it were

triggendexp={{{ [enlist{!!trigger-end}escaperegexp[]join[|]addprefix[(]addsuffix[)+]split[\/]join[/]trim[]] }}}

This worked well in the demo. I do feel it is necessary to allow the end user to very easily define the trigger-ends so I was very happy to find this solution.

@Saq, do you already now see any potential problems for this to work?

Thank you.

<:-)

Saq Imtiaz

unread,
Jul 12, 2020, 1:59:41 AM7/12/20
to TiddlyWikiDev
Hi Mat,


Type e.g [[Ed to get the popup.
Now type either of:
 - a blank space and several other words
 - or hit the Enter key a few times to get new rows
This hides the popup.
Now, where you're standing, type [[E
This shows the popup in the old place

Right. This is actually the same bug as the one we discussed before, where moving the caret with keys and then typing didnt update the position of the popup. The underlying issue is this: once you have a popup and dont explicitly dismiss it by clicking somewhere, it will continue to show at the same place. I already have ideas for how to work around this, but it's better to wait and see how the rest of the code develops first and what approach will fit best.

Regarding different trigger-end options: I have to admit I am not familiar with your code beyond what was in the simplified demo at the beginning of this thread. I think your approach should be OK though I am not clear on workflow, do users get to choose which ending to use? Anyway, best way to figure it out is to try it.

Personally I think autocompletion makes sense for some things, like links. For others, like widgets, just detecting which widget the user is trying to type and showing the relevant docs in the popup might be a better approach.

I could also imagine a popup triggered by a specific character, say "|" that lets you choose to insert a transclusion, link or image etc.... though this might be more on my mind because of the work on the floating editor toolbar and the non-selection related buttons.

Cheers,
Saq

Mat

unread,
Jul 12, 2020, 8:01:03 AM7/12/20
to TiddlyWikiDev
I must say: This is just so much fun!

Right. This is actually the same bug as the one we discussed before [...]

Good.
 
Regarding different trigger-end options: I have to admit I am not familiar with your code beyond what was in the simplified demo at the beginning of this thread. I think your approach should be OK though I am not clear on workflow, do users get to choose which ending to use? Anyway, best way to figure it out is to try it.

I'll detail my various findings below, but yes; one of the main ideas is that users should fairly easily be able to create their own popup tools. Having now tried it I'm finding it is not an issue.

But I'm curious: even for pre-made popup tools, the system will still have to know if <$widget foo> is closed or not. So how is the fragment end detected? In the EditorMagic/_Popup it is defined to be the "whole string" after the trigger until a trigger-end... but it seems your code defines the fragment as after trigger until caret. Is that correct? ...in which case I should remove the trigger-end check... but then, "until caret" can mean the rest of the whole tiddler text...? 

 
Personally I think autocompletion makes sense for some things, like links. For others, like widgets, just detecting which widget the user is trying to type and showing the relevant docs in the popup might be a better approach.

IMO widgets are so very ubiquitous so their use should be simplified as much as possible. Plus they look scary for newcomers so a popup could be a kind of wizard. I also think it were better if I could make a popup tool where there isn't such separation between docs and picking - i.e, the current popup docs approach is an iframed tw.com but this is just a compromise and it brings with it a lot of redundant/distracting stuff and it is not ideally presented. A more useful popup would perhaps show pickable parameters for each widget and info about the parameter. E.g each listed widget title could be a revealwidget to show further stuff. (Of course how to extract or rewrite the docs to fit that is a totally different matter.)

I could also imagine a popup triggered by a specific character, say "|" that lets you choose to insert a transclusion, link or image etc.... though this might be more on my mind because of the work on the floating editor toolbar and the non-selection related buttons.

Definitely a great idea. In the (full) EditorMagic demo I use "??tr" and "??dr" for transclusions where the latter opens a drawing canvas which I think is pretty neat. (In native TW, to spontaneously create and insert a sketch in the middle of a tiddler is totally impractical.) But your idea to use a common trigger, possibly even a single character as you say, is more elegant than my cryptic abbreviations.

BTW, is there something more that can be done to align EditorMagic with your floating editor toolbar? There's obvious conceptual overlap so it makes sense if they harmonize where possible. If I understand your floating editor toolbar right it is currently only triggered by selecting text. It would be cool if, for example, the user can select text which, if it is some particular string, triggers docs or something else for it that string. For example if the user, in the middle of a listwidget, selects the string $list he gets info about this, or selecting a word in some arbitrary text gives e.g a translation.

(BTW, needless to say, if there's anything in what I've created that you can use for your things I'd be incredibly flattered.)

...

OK, here's the current status: http://editormagic2.tiddlyspot.com/
(never mind the mini "quicklinks" popup unless you use the SideEditor)

It is a joy to see things pop up :-)

One problem is for EditorMagi/WidgetDocs - wich uses a selectwidget - and for EditorMagic/TransINclude - which shows an editor - the popup loses focus as soon as the selectwidget or editor is touched. Any ideas for this?

(There are still more tools I did not yet adapt.)

Thank you Saq!!!

<:-)

Saq Imtiaz

unread,
Jul 12, 2020, 10:00:31 AM7/12/20
to TiddlyWikiDev
Hi Mat,

 
But I'm curious: even for pre-made popup tools, the system will still have to know if <$widget foo> is closed or not. So how is the fragment end detected? In the EditorMagic/_Popup it is defined to be the "whole string" after the trigger until a trigger-end... but it seems your code defines the fragment as after trigger until caret. Is that correct? ...in which case I should remove the trigger-end check... but then, "until caret" can mean the rest of the whole tiddler text...? 

You have lost me here. When you refer to my code, do you mean the wiki text changes? Or the insert-completion parameter to the message? The wiki text after my modifications was largely as you had it. The insert-completion code does indeed only replace a string before the caret, which makes sense because why would you be typing and want it to replace something ahead of what you are typing?

I don't quite understand the problem you are forseeing. If you look at https://saqimtiaz.github.io/sq-tw/editormagic-popup.html#EditorMagic%2F_Popup your first list filter has a [!search::regexp<triggendexp>] that ensures we only look at incompleted widgets. All the wikitext changes I made are related to replacing the incomplete string with the completed one, not to do with detecting it. OK well, I did make sure we don't get results for incompleted links but that should not be relevant.

I don't see why you need to change anything from how it is now. The detection code is from trigger start to trigger end, the replace code doesn't care about trigger end, its a generic "replace this string just before caret with that string" kind of operation. Have you run into any issues?
 
BTW, is there something more that can be done to align EditorMagic with your floating editor toolbar?

They both make tweaks to some core widgets, so we need to make sure they can at the very least co-exist. However once again, I think the time to do that is once EditorMagic is more stable as things most likely can and will change. I have also identified some areas of the core that need patching for greater flexibility.

Beyond that, I am not sure how much I will do with the floating toolbar. Maybe a Streams addon at the most. I am extremely reluctant to release more plugins. As previously stated, my availability for the TW community will always be erratic and sporadic. I have my fingers in too many pies already and releasing plugins comes with a maintenance commitment.

The intention behind the demos I share is to hopefully inspire/provide ideas and techniques for others to follow.
 
One problem is for EditorMagi/WidgetDocs - wich uses a selectwidget - and for EditorMagic/TransINclude - which shows an editor - the popup loses focus as soon as the selectwidget or editor is touched. Any ideas for this?

Recall that the popup is a standard core RevealWidget, so it closes when you click on it unless, you also give it the class tc-popup-keep. Adding that class will fix that issue, but it will mean the popup doesn't close when you choose an autocompleted title. I recommend you add the class and leave the non-closing popup as a future issue. I have another set of changes in mind that we need to make, and that will be a good time to tackle this.

Note that  the ??tr present at the beginning of the tiddler adds a transclusion portion to every other popup created. This seems to not be an issue with an incomplete link or widget, but with ??tr so perhaps its limited to those with no end-trigger? 

Also, one of the issues I fixed in your wikitext code was the tiny grey box that shows when there is no active popup, e.g. type: "[Edit  ". This seems to be back. 



Looks like you missed some bits when integrating my code from https://saqimtiaz.github.io/sq-tw/editormagic-popup.html#EditorMagic%2F_Popup

<$list filter="""[<text>search<trigger>removeprefix<before>]
    +[!prefix[ ]splitregexp
<triggexp>]
    +[!search::regexp
<triggendexp>]
    +[last[]]""">
 <$set name=fragment filter="""[
<currentTiddler>]""" select="0">
 <$list filter="[<fragment>minlength[1]]">
 <$list filter="[all[tiddlers]prefix
<fragment>
count[]!match[0]]" variable="_NULL">
 <div style="background:white; border:1px solid silver; padding:0 5px;">

There are some changes I think we need to make next, to the order of the wikitext code that controls triggering the popup. However, I will wait for you to work out the issues discussed in this post and properly integrate my previous changes before I get into that.

Cheers,
Saq

Mat

unread,
Jul 12, 2020, 12:02:50 PM7/12/20
to tiddly...@googlegroups.com
Sorry for confusion. I did write that "Having now tried it I'm finding it is not an issue." so I only asked out of curiosity and I now understand that the replace code doesn't bother with the trigger-end, which is what I misunderstood.

[...] I have my fingers in too many pies already and releasing plugins comes with a maintenance commitment.
The intention behind the demos I share is to hopefully inspire/provide ideas and techniques for others to follow.

Fair enuff and your contributions and demos are appreciated!
 
[...] the popup loses focus as soon as the selectwidget or editor is touched. Any ideas for this?
[...] give it the class tc-popup-keep.

Thanks. I find no mention of RevealWidget (i.e reveal) in the tiddlers tagged $:/EditorMagic, Maybe it is invoked in
$:/plugins/EditorMagic/reveal-widget-tweak which I dare not touch - ?


Note that  the ??tr present at the beginning of the tiddler adds a transclusion portion to every other popup created. This seems to not be an issue with an incomplete link or widget, but with ??tr so perhaps its limited to those with no end-trigger? 

Interestingly (and luckily), it seems to be the other way around: I had mistakely kept a faux trigger-end in the tool for ??tr (i.e EditorMagic/TransINclude) and have now removed it, which also removed the undesired popup content.

[your image with the artefact]
This is related to the next issue you bring up.
 
Looks like you missed some bits when integrating my code from https://saqimtiaz.github.io/sq-tw/editormagic-popup.html#EditorMagic%2F_Popup

<$list filter="""[<text>search<trigger>removeprefix<before>]
    +[!prefix[ ]splitregexp
<triggexp>]
    +[!search::regexp
<triggendexp>]
    +[last[]]""">
 <$set name=fragment filter="""[
<currentTiddler>]""" select="0">
 <$list filter="[<fragment>minlength[1]]">
 <$list filter="[all[tiddlers]prefix
<fragment>
count[]!match[0]]" variable="_NULL">
 <div style="background:white; border:1px solid silver; padding:0 5px;">


The thing is, not every tool requires a minlength of one. The TitlePicker does because there are so many titles, but it would be a mistake to demand it for e.g widgets or macros where you might not have any idea what the initial letter is until you see it. So I moved the yellow text into the TitlePicker. Not to mention triggers like ??tr that don't have a fragment (the trigger is those four characters).

Apropos the arteface in the image you posted: This is caused from the code below the yellow, specifically the border which I've now changed to be an outline with an outline-offset:-1px to solve it.

There are some changes I think we need to make next, to the order of the wikitext code that controls triggering the popup. However, I will wait for you to work out the issues discussed in this post and properly integrate my previous changes before I get into that.

Terrific. I've updated according to my comments - which means tc-popup-keep has not been resolved and the yellow is not re-introduced but still found in TitlePicker.  By the way, I'm sorry if I seem very slow in everything but every little thing takes a lot of looking up and testing etc. Just replying to this took over an hour. I don't mind that, it is very constructive and your help is super valuable, I'm just a little stressed that you might think I'm not doing anything.

Again, thank you!

<:-)

Saq Imtiaz

unread,
Jul 12, 2020, 12:10:05 PM7/12/20
to TiddlyWikiDev
This will be short, juggling a few other things.

No stress, I know its hard to work through wikitext coding. For all its strengths it can be hard to follow.
Not using a version control like git also makes this harder, we both can't see exactly what the other person has changed.

$:/core/ui/EditTemplate/body/editor

You untagged it or just copied the changes. Remember, the edit widget in that tiddlers triggers actions, that invoke a popup with action-popupcaret. The reveal widget for the popup is inside the edit widget, as we previously discussed. 

If you keep in mind the flow between the different components that I explained earlier in this thread, I think the next steps in this development work will be a lot easier.

edit widget -> user types -> actions -> action-popupcaret -> reveal widget shows your popup tiddler.

Saq Imtiaz

unread,
Jul 12, 2020, 12:55:54 PM7/12/20
to TiddlyWikiDev
@Mat random thought that I don't have time to look into now, but if doable could be very useful here.

Right now the content of each button in the popup is:
<$text text=<<name>> />

Can we find a way to make it:
<$text text=<<name>> /> <span>X</span>

where X represents the position in the list, i.e. 1, 2, 3....

So basically we need an incrementing number.

Mat

unread,
Jul 12, 2020, 1:04:57 PM7/12/20
to TiddlyWikiDev
OK, I put in tc-popup-keep and it works perfectly. I'm not even sure what the downside is supposed to be. 

Can we find a way to make it:
<$text text=<<name>> /> <span>X</span>
where X represents the position in the list, i.e. 1, 2, 3....

If it is only a matter of visuals, I can do with with CSS. I suspect you want something more with it - ?

Next, I'll re-read your previous explanations here and keep on introducing a few other tools for testing. 

<:-)

Saq Imtiaz

unread,
Jul 12, 2020, 1:14:27 PM7/12/20
to TiddlyWikiDev
+100 to re-reading the previous explanations of the what the different bits of code do and how they work together. It will help you immensely with the next round of changes.

Can we find a way to make it:
<$text text=<<name>> /> <span>X</span>
where X represents the position in the list, i.e. 1, 2, 3....

If it is only a matter of visuals, I can do with with CSS. I suspect you want something more with it - ?

We would need to be able to set attributes like <span data-foo="1"/> 
If we can do that I think we can cheat and get some super easy keyboard shortcuts going for now.

Mat

unread,
Jul 12, 2020, 6:53:05 PM7/12/20
to TiddlyWikiDev
This adds an index:
 
<$vars count={{{ myfilter +[count[]] }}}>
<$list filter="[range
<count>]" variable=n>
<$list filter="myfilter +[nth
<n>]">
<
<n>> <<currentTiddler>><br>
</$list>
</$list>
</$vars>

Do you suggest I put this into each popup-content-tool that shows a list? (BTW, calling them popup-content-tools sucks. We need a real name.)

Off topic: I requested an array feature in the listwidget not long ago but @Jeremy explained the listwidget is already very complex. Maybe there could be an arraywidget that takes a filter and binds each item to a position. The array could be treated like a "composit variable" (yes, I just made up that term) so to call it and access a specific item one would write <<arrayname:index>> or <<arrayname|index>> or even <<arrayname##index>>. I'm thinking the latter would not clash with dic tids since the latter are invoked via transclusions. A filter operator could be array<arrayname##index>. 

Back on topic:
Just a note - I think it is your $:/core/ui/EditTemplate/body/editor that's missing the $:/EditorMagic tag. I'm only mentioning this to save you from possible confusion later if you e.g tag-drag'n-drop.

<:-)



Mat

unread,
Jul 12, 2020, 7:01:09 PM7/12/20
to TiddlyWikiDev
Q: Does a text with many "unused triggers" tax the system? Or, for that matter, also used triggers, i.e that are closed? For example, are there "event listeners" constantly pinging the system in any of the non wikitext code you made? (I only know the term "event listener" so I don't know what to look for in the code.)

<:-)

Saq Imtiaz

unread,
Jul 13, 2020, 2:33:55 AM7/13/20
to TiddlyWikiDev
Good morning Mat,

On Monday, July 13, 2020 at 12:53:05 AM UTC+2, Mat wrote:
This adds an index:
 

Using the Title Picker as an example, if we can do something like this:
<$list filter="[<fragment>minlength[1]]">
<$list filter="[all[tiddlers]prefix
<fragment>
count[]!match[0]]" variable="_NULL">

 <$list filter="""[all[tiddlers]prefix
<fragment>]""" variable=name>

 <$button class="tc-btn-invisible tc-tiddlylink">
 <$text text=<
<name>>/>

 <$action-sendmessage
 $message="tm-edit-text-operation"
 $param="insert-completion"
 text={{{[
<name>addsuffix<trigger-end>]}}}
 precursor=<
<fragment>>
 />
 <span data-tw-keyboard-shortcut="Alt+n"></span>
 </$button>
 
<br>
 </$list>
</$list>
</$list>
Where n is the index number in that list, you can use the keyboard shortcuts Alt+1, Alt+2, Alt+3 etc.... they will just automatically work. But since it would be better to add proper support for keys like arrow keys for up and down, enter key etc, don't spend too much time on this.

Regarding optimizations, performance and refactoring:

Note that this is the current flow of our code.

(in tiddler $:/core/ui/EditTemplate/body/editor)
  • User types in edit widget
  • for every keystroke edit widget invokes actions 
  • actions are in editorMagicActions macro and look like: <$action-popupcaret $state=<<qualify $:/state/EditorMagicPopupState>>/>
  • thus on every keystroke, action-popupcaret is invoked
  • so on every keystoke we trigger a popup (Reveal widget)
(in tiddler EditorMagic/_Popup )
  • popup (reveal widget) shows this tiddler
  • our list widgets and other wiki text code decide if the popup should have content.
  • If there should be content, we show it. If there should not, we try to hide it by making the popup empty and 0x0 pixels. (it would be more elegant if the popup just wasn't shown in these situations)
This is inefficient because we trigger a popup on every keystroke regardless of whether we should show a popup or note. In practice, the performance difference is probably neglible. But this is far from elegant and is also the reason it is difficult to avoid some of the issues we have with the popup appearing at its old position, even though the caret has been moved.

Also, this is why adding keyboard shortcuts like using the arrow keys is difficult. The keyboard shortcuts need to be applied to the edit widget, but all our logic for what is displayed in the popup is in the _Popup tiddler. So tying the two together is awkward. 

Instead I propose we refactor our code for the following flow (note this is all wikitext changes we are discussing here):
  • User types in edit widget
  • for every keystroke edit widget invokes actions 
  • in these actions in $:/core/ui/EditTemplate/body/editor we have our wikitext code from EditorMagic/_Popup which checks IF there is a trigger-start that should prompt the showing of a popup. 
    • Only if there is a match, do we invoke action-popup-caret.
      • We can also save extra information to the state tiddler, like what text triggered the match, what kind of popup to show (link, widget etc)
    • If there is no match, we cancel any already shown popups.
  • When the popup is shown, it reads info from the state tiddler to determine what content to show. All the wikitext related to WHAT to show stays here.
Basically it decouples detection code from display code.

This may seem like unnecessary at first glance, but it will make it far easier to have reliable and predictable behaviour and also be able to add keyboard shortcuts for arrow keys.

Cheers,
Saq
 

Mat

unread,
Jul 13, 2020, 4:13:32 AM7/13/20
to TiddlyWikiDev
If you say that's a good idea then I believe you.

Given that it's all wikitext changes, are you requesting that I implement it? I can probably do that given enough time but I'm sure there will be several missteps along the way.

Regarding the keyboard numbers your write:

But since it would be better to add proper support for keys like arrow keys for up and down, enter key etc, don't spend too much time on this.

I do think there should eventually be "regular" arrow key support so, at least for now, I'll put these numbers only in the title picker to try it out. Needing to locate, say, 7 on the keyboard doesn't quite feel like a work saver instead of arrowing through. Perhaps locating 77 on keyboard is easier but then I think it would make more sense with some key that makes the arrow jump 10 steps at a time instead.

<:-)

Saq Imtiaz

unread,
Jul 13, 2020, 4:22:40 AM7/13/20
to TiddlyWikiDev
Given that it's all wikitext changes, are you requesting that I implement it? I can probably do that given enough time but I'm sure there will be several missteps along the way.

I can help but I wont have much time until the weekend at the earliest to do any real coding on this. If you do decide to work on this yourself, questions I can try to answer more promptly. Also note that I have no real knowledge of the internals of your wikitext code beyond the title picker, so there would be a learning curve there for me as well. So I would need a chunk of uninterrupted and focused time to get started.
 

Regarding the keyboard numbers your write:

But since it would be better to add proper support for keys like arrow keys for up and down, enter key etc, don't spend too much time on this.

I do think there should eventually be "regular" arrow key support so, at least for now, I'll put these numbers only in the title picker to try it out. Needing to locate, say, 7 on the keyboard doesn't quite feel like a work saver instead of arrowing through.

It was only meant as an idea for stop-gap kb shortcuts until proper ones for arrow keys can be implemented, not an alternative. 
 
Perhaps locating 77 on keyboard is easier but then I think it would make more sense with some key that makes the arrow jump 10 steps at a time instead.

I would think that any list of results (at least for tiddler titles) should be capped to say the first 10 or so, and the user expected to type more to narrow down choices. 


Mat

unread,
Jul 13, 2020, 4:49:05 AM7/13/20
to TiddlyWikiDev
I can help but I wont have much time until the weekend at the earliest to do any real coding on this. If you do decide to work on this yourself, questions I can try to answer more promptly.

I'll start and we'll see how it goes :-)
 
Also note that I have no real knowledge of the internals of your wikitext code beyond the title picker, so there would be a learning curve there for me as well. So I would need a chunk of uninterrupted and focused time to get started.

Haha, the only thing that would be challenging is to understand the errors I make.

 
It was only meant as an idea for stop-gap kb shortcuts until proper ones for arrow keys can be implemented, not an alternative. 

OK, I'll put it in the titlepicker to see how it performs.


I would think that any list of results (at least for tiddler titles) should be capped to say the first 10 or so, and the user expected to type more to narrow down choices. '

That only works if you know the name of what you're looking for though, so you can at least type its initial.
I'm thinking maybe the standard search mechanism could be hijacked in some cases, so to find e.g a title you can type a tag. Only relevant for some of the tools, and I haven't thought it through.

Mat

unread,
Jul 13, 2020, 10:00:32 AM7/13/20
to TiddlyWikiDev
OK, so I made this which does not work: http://editormagic2.tiddlyspot.com/

1) How much stuff can actually be put in editorMagicActions() without overloading the poor inputActions parameter? A simpler filter surrounding the $action-popupcaret call did work.

2) Any idea for how to put in flags in the inputActions parameter argument that somehow comes thorough so they can be seen? I don't expect there to be a way, it would just simplify tests if there is.

3) Is my attempt just totally off? Perhaps I shouldn't put stuff directly in the inputActions parameter at all. Maybe the mechanism should be used to decide if that whole editor call should be used or if a fallback editor should be used?
 
P.S I'm aware the _Popup will also need mods but I don't think that is why no popup shows with the above attempt.

<:-)

Mat

unread,
Jul 13, 2020, 10:12:30 AM7/13/20
to TiddlyWikiDev
1) How much stuff can actually be put in editorMagicActions() without overloading the poor inputActions parameter? A simpler filter surrounding the $action-popupcaret call did work.

Better phrased: What are the rules for what is allowed as an attribute argument - and in what way am I breaking them in my attempt?

<:-)

Saq Imtiaz

unread,
Jul 13, 2020, 10:23:58 AM7/13/20
to tiddly...@googlegroups.com
Don't think there is anything wrong with your code. The issue is probably this:
- the code relies on selectionEnd, which we dont have access to since that is provided by action-popupcaret

Possible options:
a) don't rely on selectionEnd for detection (though this might get inconsistent like before)
b) wait for me to have time to fiddle. There is a widget I wrote for streams that should be usable to avoid these issues.

 I can try to find time for this tonight or tomorrow morning.

--
You received this message because you are subscribed to a topic in the Google Groups "TiddlyWikiDev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/tiddlywikidev/hOlWpnejqvI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to tiddlywikide...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/tiddlywikidev/5456aa56-a9f4-472d-9a00-f528f7269045o%40googlegroups.com.

Mat

unread,
Jul 13, 2020, 10:51:51 AM7/13/20
to TiddlyWikiDev
OK thanks, I'll see if I can just get it working, even if inconsistently, in which case I can instead work on _Popup.

What exactly does this do: "[{!!text}split[]first<selectionEnd>join[]]"  - maybe discard everything in the full text after the fragment? I need to know in order to replace selectionEnd with something, so to say.

<:-)

Saq Imtiaz

unread,
Jul 13, 2020, 12:00:09 PM7/13/20
to TiddlyWikiDev
Hi Mat,

selectionEnd is the end caret position. So we split to get individual characters, keep only what is before selectionEnd, and join back to a string. 

selectionEnd and what it is used for is explained earlier in the thread. Part of the motivation for putting in so much time in the explanations in this thread is for it to serve as dev documentation, and to make sure you are able to follow, further develop and maintain the wikitext portions of the code. So when in doubt, it's worth checking if the info you need is in the thread. This is not criticism, just a reminder so you hopefully don't get stalled when I am not around, if it can be avoided.

Give this a go and see if it works:

If so, you can keep working on the wikitext, and I will explain the changes later. The changes are not in the editorMagicActions or the popup. So if it works, you should be good to continue for now.

I wonder if it would make things easier if you used a TW file hosted on github with the git saver, so I could easily see what had changed in each file. I haven't used the git saver but it should in theory be as easy as using tiddlyspot.

Cheers,
Saq

Mat

unread,
Jul 13, 2020, 12:38:46 PM7/13/20
to TiddlyWikiDev
Appreciated. It wasn't really selectionEnd that I wondered about but more that full filter construct and split[] that didn't quite make sense... but now it seems obvious ;-) But, yeah, I should probably check back even more in your posts regardless. Thanks for being so detailed. And patient!

Give this a go and see if it works:

IF these changes are also supposed to deal with the move-with-arrow-keys issue, then that aspect does not seem to work fully yet. But, yes, it does show the popup and I'll continue with the wikitext. (My first tests indicate I must keep the trigger controls etc in _Popup anyway, making for such checks both there and around the $action-popupcaret.)
 

I wonder if it would make things easier if you used a TW file hosted on github with the git saver, so I could easily see what had changed in each file. I haven't used the git saver but it should in theory be as easy as using tiddlyspot.

I have not used it either. I'll do a quick investigation but given my failing adventures with gh at large, I kind of doubt it will be as simple to use as tiddlyspot.

Thank you.

<:-)

Saq Imtiaz

unread,
Jul 13, 2020, 1:50:27 PM7/13/20
to TiddlyWikiDev
@Mat
 
IF these changes are also supposed to deal with the move-with-arrow-keys issue, then that aspect does not seem to work fully yet. But, yes, it does show the popup and I'll continue with the wikitext. 
 

My changes today are meant solely to address the missing selectionEnd variable after we moved the trigger code from the _Popup tiddler to the editor tiddler.

The refactoring changes you are making, open the door to solving the move-with-arrow-keys issue.

If you look at my description from earlier of the proposed flow after refactoring (reproduced below), we haven't yet implemented the part in yellow. However, we now have that possibility. This might require JS or it might be as simple as deleting the state tiddler.

Instead I propose we refactor our code for the following flow (note this is all wikitext changes we are discussing here):
  • User types in edit widget
  • for every keystroke edit widget invokes actions 
  • in these actions in $:/core/ui/EditTemplate/body/editor we have our wikitext code from EditorMagic/_Popup which checks IF there is a trigger-start that should prompt the showing of a popup. 
  • Only if there is a match, do we invoke action-popup-caret.
  • We can also save extra information to the state tiddler, like what text triggered the match, what kind of popup to show (link, widget etc)
  • If there is no match, we cancel any already shown popups.
  • When the popup is shown, it reads info from the state tiddler to determine what content to show. All the wikitext related to WHAT to show stays here.
 

 (My first tests indicate I must keep the trigger controls etc in _Popup anyway, making for such checks both there and around the $action-popupcaret.)

A possible approach here is to save the detected fragment, and the type of autocompletion in the state tiddler and read it from there in the popup. Then the popup just needs to display the appropriate content. The code around $action-popupcaret would handle detection, the code in the popup would handle display.

Example pseudocode:
<$action-popupcaret $state=<<qualify $:/state/EditorMagicPopupState>>/>
<$action-setfield $tiddler=<<qualify $:/state/EditorMagic/PopupState>> em-fragment=<<fragment>> em-triggerType=<<triggerType>>/>

An explanation of how to set a variable available in the popup, from the state tiddler, is provided earlier in the thread.

Either you need to extend trigger definitions with a "type", eg widget, links etc. Or, be able to use the <<trigger>> (<< or <$ etc) for the purpose of knowing what display logic to use. 

So in the popup:
triggerType is "link" -> transclude tiddler for links, which displays links that match "fragment"
or triggerType is "widget" -> transclude tiddler for widgets, which displays links that match "fragment"
or trigger is "<$" -> transclude tiddler for widgets....

This is all pseudocode and talking off the top of my head, so don't take it too literally. I hope it serves as an example of how to convey information to the popup and avoid having the detection code in two places.


I wonder if it would make things easier if you used a TW file hosted on github with the git saver, so I could easily see what had changed in each file. I haven't used the git saver but it should in theory be as easy as using tiddlyspot.

I have not used it either. I'll do a quick investigation but given my failing adventures with gh at large, I kind of doubt it will be as simple to use as tiddlyspot.

I would hope its as simple as, set up a github repo to use github pages, upload file via web interface. Then load it via web URL and save as you would on tiddlyspot.
 
Cheers,
Saq

Mat

unread,
Jul 13, 2020, 6:47:59 PM7/13/20
to tiddly...@googlegroups.com
OK, complex stuff. Status for  http://editormagic2.tiddlyspot.com/  is described here:

All noteworthy changes is in /body/editor - in effect I've transferred everything from /_Popup , effectively integrating the $action-popupcaret call with the other popup stuff. This may be a mistake and you suggest another route which I will attempt tomorrow.

I intentionally put a green border on the popup to get the artefact to indicate that the popup is active and where it is.

Other:
  • User types in edit widget 
  • for every keystroke edit widget invokes actions 
(check, check)
  • in these actions in $:/core/ui/EditTemplate/body/editor we have our wikitext code from EditorMagic/_Popup which checks IF there is a trigger-start that should prompt the showing of a popup. 
check 
  • Only if there is a match, do we invoke action-popup-caret.
check 
  • We can also save extra information to the state tiddler, like what text triggered the match, what kind of popup to show (link, widget etc)
check for which popup content to show
  • If there is no match, we cancel any already shown popups.
failed attempt - I made a "deletePopState" macro but calling it gives RSOE Uncaught TypeError: Cannot read property 'left' of undefined
(to locate the call: it's in editorMagicActions in the inner ListWidgets emptyMessage )

  • When the popup is shown, it reads info from the state tiddler to determine what content to show. All the wikitext related to WHAT to show stays here.
not done yet 


Either you need to extend trigger definitions with a "type", eg widget, links etc. Or, be able to use the <<trigger>> (<< or <$ etc) for the purpose of knowing what display logic to use. 

I just save the popup tool name (ref to as "template" in the code) in the statetiddler.
 
git saver
 
Edit: Enough to say, I don't succeed with it.

<:-)

Mat

unread,
Jul 14, 2020, 6:17:42 AM7/14/20
to tiddly...@googlegroups.com
OK, updated http://editormagic2.tiddlyspot.com/

I think I've now managed to separate concerns between the /body/editor and /_Popup. It is worth noting that what exact data that should be stored in the state tiddler or which variables that should be defined in /_Popup can depend on what the end popup content tools need. Currently, the only defined variables in _Popup are "tid" and "text" (not ideal variable names btw).

  • If there is no match, we cancel any already shown popups.
I'm not sure how to handle this, see previous comment.


 Things are getting really to look pretty darn cool!!!

<:-)

Saq Imtiaz

unread,
Jul 14, 2020, 6:31:00 AM7/14/20
to tiddly...@googlegroups.com
Mat: Busy day but I'll make some time to read, catch up and review in the afternoon.

On Tue, Jul 14, 2020 at 12:17 PM Mat <matia...@gmail.com> wrote:
OK, updated http://editormagic2.tiddlyspot.com/

I think I've now managed to separate concerns between the /body/editor and /_Popup. It is worth noting that what exact data, and which exact values that should be stored in the state tiddler or which variables that should be defined in /_Popup can depend on what the end popup content tools need. Currently, the only defined variables in _Popup are "tid" and "text" (not ideal variable names btw).

  • If there is no match, we cancel any already shown popups.
I'm not sure how to handle this, see previous comment.


 Things are getting really to look pretty darn cool!!!

<:-)

--
You received this message because you are subscribed to a topic in the Google Groups "TiddlyWikiDev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/tiddlywikidev/hOlWpnejqvI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to tiddlywikide...@googlegroups.com.

Mat

unread,
Jul 14, 2020, 7:38:17 AM7/14/20
to TiddlyWikiDev
Saq, no rush whatsoever.

I just also updated the TitlePicker to include that keyboard shortcut code. It doesn't do anything so I'm guessing something more is needed.

<:-)

Saq Imtiaz

unread,
Jul 14, 2020, 8:07:20 AM7/14/20
to TiddlyWikiDev
Make sure you use the exact attribute name that I mentioned earlier, and that the span is inside the button for each list result.
If that doesn't help, I'll debug later.

Mat

unread,
Jul 14, 2020, 8:26:17 AM7/14/20
to TiddlyWikiDev
Thanx, it was indeed misplaced outside of the button. It now works but no trigger-end is appended. I'm leaving it for your to look at.

<:-)

Saq Imtiaz

unread,
Jul 14, 2020, 8:29:16 AM7/14/20
to tiddly...@googlegroups.com
Have you made trigger-end available as a variable in the popup?

On Tue, 14 Jul 2020, 14:26 Mat, <matia...@gmail.com> wrote:
Thanx, it was indeed misplaced outside of the button. It now works but no trigger-end is appended. I'm leaving it for your to look at.

<:-)

--
You received this message because you are subscribed to a topic in the Google Groups "TiddlyWikiDev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/tiddlywikidev/hOlWpnejqvI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to tiddlywikide...@googlegroups.com.

Mat

unread,
Jul 14, 2020, 9:20:20 AM7/14/20
to TiddlyWikiDev
Saq Imtiaz wrote:
Have you made trigger-end available as a variable in the popup?

Doh! Now added and it works.

<:-)

Saq Imtiaz

unread,
Jul 14, 2020, 9:33:47 AM7/14/20
to TiddlyWikiDev
I feel like with the hit rate of these guesses I should be playing the lottery. About to take a look at your demo now.

Saq Imtiaz

unread,
Jul 14, 2020, 10:13:51 AM7/14/20
to TiddlyWikiDev
@Mat:
 
  • If there is no match, we cancel any already shown popups.
failed attempt - I made a "deletePopState" macro but calling it gives RSOE Uncaught TypeError: Cannot read property 'left' of undefined
(to locate the call: it's in editorMagicActions in the inner ListWidgets emptyMessage )


This is probably because you are inside a list widget, so for every type of autocomplete defintion (eg widget, macro, etc) that doesn't match, you end up deleting the state tiddler even if there was a match in another type of autocomplete defintion.

For example:
- no match for <$ -> delete state tiddler
- match for <<  -> create state tiddler and popup
- no match for [[ -> delete state tiddler

The logic needs to be:
- loop through all autocomplete definitions
- if any of them match -> trigger popup
- if none of them match -> delete state tiddler

I think we could avoid having to resort to JS here, through everyones favourite technique: recursive macros.
If you want to take a crack go ahead, otherwise I think its ok to leave it alone for now and I'll look into it when I have more time.

By the way, how do we determine priority? I mean if we have an incomplete [[ and <$ how is it determined which is being completed? Should be the one closest to the caret, not sure if that is how it is already and if so, how that is ensured.

Overall I think it's definitely headed in the correct direction and you've done a good job with the refactoring.

I note that we have multiple <<qualify $:/state/EditorMagicPopupState>> in the body/editor tiddler. One single vars/set widget around the edit widget, assigning this to something like em-state would make it available in the popup and in our actions.
 
Agreed on variable names needing work, same for field names set by action-caretpopup (I've added a note that I need to do this for the JS bits). Recommend prefixing all fields and variables you set with em- and otherwise making names a bit more self explanatory. 

All of the code does need a proper pass through for consistency before any kind of public sharing. That should come after it is relatively stable functionality wise though.

For instance, the action-withselection widget I modified from streams to facilitate this re-factoring, can and should be made consistent with what is used in Streams so that there are less maintenance issues going forwards. Depending on the final shape this takes, there may also be room to simplify some of the code by means of some core PRs.
  • When the popup is shown, it reads info from the state tiddler to determine what content to show. All the wikitext related to WHAT to show stays here.
It is almost like the popup is just a template now that shows information based on what is in the state tiddler, by transcluding other tiddlers. A very TW approach in my opinion.
 
I wonder if would be helpful to set currentTiddler={{{[<q-state>get[template]]}}} at the beginning of the popup, allowing you to access trigger as {{!!trigger}} etc. This is more a question of coding style and preference though.

 
git saver
 
Edit: Enough to say, I don't succeed with it.

I took a quick look and did get it working. With proper instructions it is actually not difficult and can all be setup via the github web interface. I will write up instructions when I have time. It makes usage as easy as tiddlyspot, but with the benefit of being able to see a diff of what has changed, which is a great help for collaboration. 


I can use as normal and it saves back to github.

Note that the patch which adds inputActions to the edit widget has been merged as is now part of the latest pre-release.

Cheers,
Saq

Mat

unread,
Jul 14, 2020, 12:08:29 PM7/14/20
to TiddlyWikiDev
Saq Imtiaz wrote:
This is probably because you are inside a list widget, so for every type of autocomplete defintion (eg widget, macro, etc) that doesn't match, you end up deleting the state tiddler even if there was a match in another type of autocomplete defintion.

Aaah, of course.
 
The logic needs to be:
- loop through all autocomplete definitions
- if any of them match -> trigger popup
- if none of them match -> delete state tiddler

I had a go using another logic. It almost works:

\define deletePopState()
<$list filter="[<em-state>get[template]!match<template>]">
<$action-deletetiddler $tiddler=<<em-state>>/>
</$list>
\end

I.e only delete if what is currently investigated does not match the template in use. Problem is, there is no "template in use" until one has been set. But if we could set a faux template value in em-state to begin then nothing will match this, until the template in use is set, upon which no subsequent investigation will match that either. I think it could work... but it would also mean there'd be a state tiddler with the faux, then real value, hanging around, perhaps until deleted when tiddler closed. Not a good solution but I'm mentioning it in case it gives you ideas.

As you note I also followed your advice and introduced an "em-state" variable instead of calling the qualify macro all the time.

By the way, how do we determine priority? I mean if we have an incomplete [[ and <$ how is it determined which is being completed? Should be the one closest to the caret, not sure if that is how it is already and if so, how that is ensured.

That sounds like my original problem in trying to decide where a string ended and which was seemingly magically solved once you stepped in. But... yeah, isn't it automatically the one closest to the left of the last key stroke?


Overall I think it's definitely headed in the correct direction and you've done a good job with the refactoring.

That's encouraging to hear. Your instructions are, obviously, indispensible.

  • When the popup is shown, it reads info from the state tiddler to determine what content to show. All the wikitext related to WHAT to show stays here.
It is almost like the popup is just a template now that shows information based on what is in the state tiddler, by transcluding other tiddlers. A very TW approach in my opinion.

Yes. Interestingly, the popup content tiddlers are also basically templates. As I've mentioned, one hope is for users to be able to create these "end templates" themselves, since we probably can't predict what they'll want access to, so I'm wondering what can be moved upstream into the popup. They're a bit too complex now, I feel, but I'm not sure what is general enough to move.

 I wonder if would be helpful to set currentTiddler={{{[<q-state>get[template]]}}} at the beginning of the popup, allowing you to access trigger as {{!!trigger}} etc. This is more a question of coding style and preference though.

Yes, this is exactly one of those things, assuming I understand you right. A user constructing his own template will be very confused if {{!!trigger}} does not access the templates trigger value.

 
git saver
I took a quick look and did get it working.

I can tell you didn't see my reply before I re-edited my post ;-) As for seeing diffs, isn't there a plugin with this feature? Maybe it's only for TW on node. 

But if there was some kind of git saver that made it possible to use a TW as a proper multi user wiki, that would make it very worthwhile for me to grab the bull by the horns and study this properly. (As I indicated in my deleted text; I have tried, quite a lot actually). Do you think that would be possible - i.e a published wiki on gh that many people can edit... including some checkin/out or versioning...?


Note that the patch which adds inputActions to the edit widget has been merged as is now part of the latest pre-release.

Yay!

<:-)

Saq Imtiaz

unread,
Jul 14, 2020, 1:33:22 PM7/14/20
to TiddlyWikiDev
@Mat:


I.e only delete if what is currently investigated does not match the template in use. Problem is, there is no "template in use" until one has been set. But if we could set a faux template value in em-state to begin then nothing will match this, until the template in use is set, upon which no subsequent investigation will match that either. I think it could work... but it would also mean there'd be a state tiddler with the faux, then real value, hanging around, perhaps until deleted when tiddler closed. Not a good solution but I'm mentioning it in case it gives you ideas.

I'll try to find time to investigate this weekend.
 
By the way, how do we determine priority? I mean if we have an incomplete [[ and <$ how is it determined which is being completed? Should be the one closest to the caret, not sure if that is how it is already and if so, how that is ensured.

That sounds like my original problem in trying to decide where a string ended and which was seemingly magically solved once you stepped in. But... yeah, isn't it automatically the one closest to the left of the last key stroke?

I am juggling quite a few things today and not the most clearheaded. I'll revisit this later to make sure this behaviour is intentional and reliable and not an accident that we cannot rely on. 

 

Overall I think it's definitely headed in the correct direction and you've done a good job with the refactoring.

That's encouraging to hear. Your instructions are, obviously, indispensible.

Part of my goal here is to make sure you are comfortable with the wikitext portion of the code, so that if this does get into shape for release you are able to maintain it and provide support. 

It is almost like the popup is just a template now that shows information based on what is in the state tiddler, by transcluding other tiddlers. A very TW approach in my opinion.

Yes. Interestingly, the popup content tiddlers are also basically templates. As I've mentioned, one hope is for users to be able to create these "end templates" themselves, since we probably can't predict what they'll want access to, so I'm wondering what can be moved upstream into the popup. They're a bit too complex now, I feel, but I'm not sure what is general enough to move.

Yeah its a bit like the pattern in: tidder -> ViewTemplate -> tiddlers tagged $:/tags/ViewTemplate. 
I admit I haven't looked much if at all at the popup content tiddlers. When I find the time I'll have a look to see what can be done in terms of simplifying them.
 
git saver
I took a quick look and did get it working.

I can tell you didn't see my reply before I re-edited my post ;-) As for seeing diffs, isn't there a plugin with this feature? Maybe it's only for TW on node. 

I did, email subscription to the Dev group ;)

I will write up instructions for using the web interface when I get the chance, and I'll encourage you to give it a go at that time. It may feel like there isn't much benefit in it for you, but it would make it a lot easier to collaborate with you and offer assistance. Even in this project, as it grows more complex, we are nearing the point where it takes me more time to figure out what you have changed, rather than study the changes itself. It's the difference between easily being able to take a look at what you are doing and offering feedback when I have a few minutes to spare, vs having to wait until I have a solid chunk of time (which can be a while!). :)
 

But if there was some kind of git saver that made it possible to use a TW as a proper multi user wiki, that would make it very worthwhile for me to grab the bull by the horns and study this properly. (As I indicated in my deleted text; I have tried, quite a lot actually). Do you think that would be possible - i.e a published wiki on gh that many people can edit... including some checkin/out or versioning...?

Possible, of course. But the checkin/out and versioning would take a fair bit of work. Even now you could have two people with access to the same github repo and both could write to the wiki, but then the usual risks of overwriting each others changes apply.

Cheers,
Saq

Mat

unread,
Jul 14, 2020, 2:44:10 PM7/14/20
to TiddlyWikiDev
Saq Imtiaz wrote:
I'll try to find time to investigate this weekend.

Excellent. 

Part of my goal here is to make sure you are comfortable with the wikitext portion of the code, so that if this does get into shape for release you are able to maintain it and provide support. 

Even more excellent.

 the popup content tiddlers. When I find the time I'll have a look to see what can be done in terms of simplifying them.

Thanks. I didn't add all of them yet and they're not very polished even if the structure of them is valid.

github
I will write up instructions for using the web interface when I get the chance, and I'll encourage you to give it a go at that time.

Thanks, that's really kind of you and should be of benefit also for others. I understand the frustration it's causing you.

<:-)

Saq Imtiaz

unread,
Jul 15, 2020, 4:07:09 PM7/15/20
to TiddlyWikiDev
@Mat this is a rush job so I don't think its quite right/complete, and I didnt get the chance to test much, but try this. Make a backup first!

Replace your editorMagicActions macro with:

\define processNextMagicActionsTiddler()
<$list filter="""[all[tiddlers]tag[$:/tags/EditorMagic]!has[draft.of]after<currentTiddler>]""" emptyMessage=<<deletePopState>>>
<<processMagicActionsTiddler>>
</$list>
\end

\define processMagicActionsTiddler() 
<$vars
       template={{!!title}}
       trigger={{!!trigger}}
       trigger-end={{!!trigger-end}}
       triggexp={{{ [{!!trigger}escaperegexp[]] }}}
       triggendexp={{{ [enlist{!!trigger-end}escaperegexp[]join[|]addprefix[(]addsuffix[)+]split[\/]join[/]trim[]] }}} 
   before={{{ [<text>splitbefore{!!trigger}] }}}
   magic-actions-tiddler=<<currentTiddler>>
>
<$list filter="""[<text>search<trigger>removeprefix<before>] +[!prefix[ ]splitregexp<triggexp>] +[!search::regexp<triggendexp>] +[last[]]""" emptyMessage=<<processNextMagicActionsTiddler>>>
   <<popupcaret>>
  <!-- <<processNextMagicActionsTiddler>>-->
</$list>
</$vars>
\end

\define editorMagicActions()
<$vars text={{{ [{!!text}split[]first<selectionEnd>join[]] }}} >
<$list filter="""[all[tiddlers]tag[$:/tags/EditorMagic]!has[draft.of]first[]]""">
<$vars matched="false">
<<processMagicActionsTiddler>>
</$vars>
</$list>
</$vars>
\end


Mat

unread,
Jul 15, 2020, 5:21:02 PM7/15/20
to TiddlyWikiDev
@Saq, I'm really looking forward to try it out but I'm afraid this will at earliest be done tomorrow night.

<:-)

Saq Imtiaz

unread,
Jul 15, 2020, 5:49:13 PM7/15/20
to tiddly...@googlegroups.com
No rush. In fact, maybe leave that alone and consider this other issue instead.

I think there's definitely an issue with the code that was introduced when it went from being just a title picker as in the start of this thread, to adding a list that loops through all the tiddlers tagged $:/tags/EditorMagic. I think when there are multiple possible matches (of different types, widget and title for example), the last one wins, where the order is the tag order. Which means that in the following text with the caret at the end of the text:
<$ac [[ <<

the widget picker is active due to tag order, but wont show any matches.

What I fixed with my orginal demo for you is that if there are multiple incomplete matches for title, we only consider the last. However we now have a list which checks for matches for multiple triggers, with no way of deciding which one wins when there are multiple matches.

Saq Imtiaz

unread,
Jul 16, 2020, 12:36:36 PM7/16/20
to TiddlyWikiDev
@Mat do not test the code I posted yesterday, I did some more tinkering late last night. Just need to find time to look through it carefully and test.


On Wednesday, July 15, 2020 at 11:21:02 PM UTC+2, Mat wrote:

Mat

unread,
Jul 16, 2020, 12:50:18 PM7/16/20
to TiddlyWikiDev
Saq Imtiaz wrote:
@Mat do not test the code I posted yesterday, I did some more tinkering late last night. Just need to find time to look through it carefully and test.

Thanks Saq, including thanks for the "warning". Looking forward to whenever it comes.

<:-)

Saq Imtiaz

unread,
Jul 16, 2020, 1:02:34 PM7/16/20
to TiddlyWikiDev
@Mat the code is messy but if you want to test the latest working version is here:

Also, if you look at the Browser Developer tools console (ctrl+shift+I on chrome), there is some additonal debugging going on. 

+1 to what you did with the test tiddler, I always do that sort of thing to help debug actions.

Saq Imtiaz

unread,
Jul 16, 2020, 4:19:18 PM7/16/20
to TiddlyWikiDev
Mat: I've renamed the macros to facilitate comprehension. Beyond that I will wait for you to verify that the behaviour is correct before cleaning up the code further.

Note that I've tried to address both the issue with deleting the popup state when there are no matches, as well as making sure it is the last match (closest to the caret) that triggers the popup, rather than it being based on tag order as it was before.

Mat

unread,
Jul 16, 2020, 4:24:25 PM7/16/20
to TiddlyWikiDev
@Saq, thank you. 

First regarading:

Also, if you look at the Browser Developer tools console (ctrl+shift+I on chrome), there is some additonal debugging going on. 

If I interpret it correctly, that's why the iframe for WidgetDocs doesn't work.

I'm guessing the above does not have anything to do with the fact that typing <$ now only shows one popup content, as opposed to two contents previously i.e both WidgetDocs and the WidgetPicker that use the same trigger. I.e can a trigger now only trigger a single content in the popup? (namely thei first title, alphabetically). This is not a problem (one can modify the popup content to feature multiple things if one wants to.)

About ../body/editor 

That's some pretty advanced coding now. Lots of levels - which might not be desirable per se but I'm impressed how/that you seem to have solved it. I don't understand how you realized you should do a recursive popping back and forth between processM..A..T and processNext.. but well done.
BTW, I think magic-actions-tiddler variable is unused.
...and $action-log is that for testing?


+1 to what you did with the test tiddler, I always do that sort of thing to help debug actions.

Yeah, it was needed. Side note: May I ask if you use any particular tools for your dev? For one thing, I assume you don't develop directly in TW as I do (in the SideEditor) but I never understood how it can be effective to not see the results directly. Or do you, somehow see the results live?

Tomorrow I will implement the bit about:

 I wonder if would be helpful to set currentTiddler={{{[<q-state>get[template]]}}} at the beginning of the popup, allowing you to access trigger as {{!!trigger}} etc. This is more a question of coding style and preference though.

What other things can you think of that I can do? 

Now I see a forum note about a new message here, so I'll post this before writing further.

<:-)

Saq Imtiaz

unread,
Jul 16, 2020, 4:27:52 PM7/16/20
to tiddly...@googlegroups.com
The only changes while our messages crossed where renaming macros and removing unused variables

--
You received this message because you are subscribed to a topic in the Google Groups "TiddlyWikiDev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/tiddlywikidev/hOlWpnejqvI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to tiddlywikide...@googlegroups.com.

Mat

unread,
Jul 16, 2020, 4:31:10 PM7/16/20
to TiddlyWikiDev
Saq Imtiaz wrote:
Mat: I've renamed the macros to facilitate comprehension. Beyond that I will wait for you to verify that the behaviour is correct before cleaning up the code further.

OK, as you see in my previous post I did fool around a bit with it and I think it works correctly (except the iframe but I guess that's not what we're dealing with right now). 

Note that I've tried to address both the issue with deleting the popup state when there are no matches, as well as making sure it is the last match (closest to the caret) that triggers the popup, rather than it being based on tag order as it was before.

Yes, this is very good. Looks great to delete one character at a time in that string with triggers and have a new pop up show with the correct content and at correct location - and no green artifact if there is no trigger :-D

BTW, I'll also polish the popup and the popup content tomorrw.

Now another forum alert about new message. We're posting past eachothers.

<:-)

Mat

unread,
Jul 16, 2020, 4:34:14 PM7/16/20
to TiddlyWikiDev
Saq Imtiaz wrote:
The only changes while our messages crossed where renaming macros and removing unused variables

Excellent. Will look closer tomorrow and polish up on things. 

<:-)

Mat

unread,
Jul 16, 2020, 5:07:11 PM7/16/20
to tiddly...@googlegroups.com
Just noted something; typing e.g [[xxxxxx will trigger the popup (i.e the mere artifact) in spite of no tiddler prefixed such. Is this a problem? If it is, I'm thinking some "late" filter is needed, i.e after the mechanism knows what type of "thing" is looked at (i.e is it a title or a macroname, etc) ...so it if we want to keep the separation of concerns between /body/editor and /Popup, I guess this should also go into /body/editor somewhere... IFF this all is a problem. 

<:-)

Saq Imtiaz

unread,
Jul 16, 2020, 5:44:52 PM7/16/20
to TiddlyWikiDev
@Mat replies inline

Also, if you look at the Browser Developer tools console (ctrl+shift+I on chrome), there is some additonal debugging going on. 

If I interpret it correctly, that's why the iframe for WidgetDocs doesn't work.

There is an error logged to do with the iframe, but that's not due to anything I've changed.
Mixed Content: The page at 'https://saqimtiaz.github.io/sq-tw/em3.html' was loaded over HTTPS, but requested an insecure frame 'http://tiddlywiki.com/static/ActionCreateTiddlerWidget.html'. This request has been blocked; the content must be served over HTTPS.
 
I'm guessing the above does not have anything to do with the fact that typing <$ now only shows one popup content, as opposed to two contents previously i.e both WidgetDocs and the WidgetPicker that use the same trigger. I.e can a trigger now only trigger a single content in the popup? (namely thei first title, alphabetically). This is not a problem (one can modify the popup content to feature multiple things if one wants to.)

Yes, this was a necessary change to ensure that only the trigger closest to the caret triggers a popup. If 2 triggers are the same, they are equally close to the popup and can't be distinguished so the first one wins.
 

About ../body/editor 

That's some pretty advanced coding now. Lots of levels - which might not be desirable per se but I'm impressed how/that you seem to have solved it. I don't understand how you realized you should do a recursive popping back and forth between processM..A..T and processNext.. but well done.

It's just a recursive macro. The em-checkNextTrigger macro is just the emptyMessage from em-checkTrigger, moved to an external macro for readability. All it does is choose the next "definition" tiddler and call em-checkTrigger.

Basically, a normal list widget is great when you want to perform an action for every result. That is not what we want. We want to test all definition tiddlers for matches, and at the end decide what to do. That requires a recursive macro, setting variables before calling itself again. This way the values of the variables are remembered from step to step. 
 
...and $action-log is that for testing?

Yes, at its simplest when it runs it logs all variables to the console in a nice table.
 

Side note: May I ask if you use any particular tools for your dev? For one thing, I assume you don't develop directly in TW as I do (in the SideEditor) but I never understood how it can be effective to not see the results directly. Or do you, somehow see the results live?

I do work with node and tiddlers as separate files. I don't really need to save and reload often, I think that's the key. Usually I can write a set of actions like the ones we are dealing with here in one go. If they don't quite work right away, there isnt much trial and error. It is more a case of analyizing the logged variables to figure out where its going wrong.

 
What other things can you think of that I can do? 

All variables need to renamed, to have a prefix, like em-, em-detection-, em-display-
The idea is both to avoid name clashes with user macros but also to make the names more self explanatory. So more descriptive names instead of "tid" or "fragment". Suggest you don't do this for the body/editor code until I am done cleaning up there. I can't comment on the popup tiddlers as I have not looked at them yet.

Just noted something; typing e.g [[xxxxxx will trigger the popup (i.e the mere artifact) in spite of no tiddler prefixed such. Is this a problem? If it is, I'm thinking some "late" filter is needed, i.e after the mechanism knows what type of "thing" is looked at (i.e is it a title or a macroname, etc) ...so it if we want to keep the separation of concerns between /body/editor and /Popup, I guess this should also go into /body/editor somewhere... IFF this all is a problem. 

Yes, this is why it was difficult to ensure that we only show a popup for the last trigger before the caret. The same problem exists for widgets and macros, eg <$xxxx or <<xxxx

The title picker trigger detection considers this a valid match:
[[$:/themes/ <$ <<xxxxx <$accccccc"

This is a basic shortcoming of the way you have designed the trigger detection. Ideally instead of a regexp just checking for say <$ you would check also for what comes after that, which character are allowed and which not. I am not sure how much flexibility the regexp implementation in TW offers us though. So this definitely isn't ideal and I did think about bringing this up while tweaking the code last night and today. Resolving this may also allow us to make the recursive multi level list code in body/editor simpler, but woul add its own complexity.

 It may be something we can live with, if it doesn't cause visual artifacts or performance issues. Otherwise we could consider a second regexp check for the "fragment" after the caret. I would say leave it alone for now, but be prepared to have to deal with it.

I'll clean up the body/editor code sometime this weekend.
Cheers,

Saq

Mat

unread,
Jul 17, 2020, 10:44:26 AM7/17/20
to TiddlyWikiDev

First, unless you object, I will hereon refer to the end user popup content templates as "popup tools" or, if the context allows, just "tools". And we can now call the /_Popup tiddler simply "the popup".

The popup is now fully reworked. It has two groups of variables. See if you think any of them should be moved upstreams into /body/editor. It feels like the popup ought not have anything to do with the state tiddler. BTW, the editedTiddler variable refers to the viewtemplate tiddler of a tiddler being edited; in our case it'd be "RikerIpsum", and this variable is used in e.g transclude tools.

Changing variable names is not as obvious as I thought: The system variables should be prefixed with em-. But IMO variables that the user is in direct contact with should be as friendly as possible. For example, when he creates a popup tool I think it is better if he creates the "trigger" field as opposed to the "em-trigger" field. Yes/no?
And "fragment"... I guess it could be changed into "nameprefix" or "em-nameprefix" but I'm not sure that is more informative. It must not be "titleprefix" because it is not always titles.)

3) The "false fragment problem" i.e that  <$xxxx or <<xxxx triggers the popup:
[...] leave it alone for now, but be prepared to have to deal with it.
OK.
....

Q's for you

1) The styling you've put in $:/plugins/EditorMagic/styles - mess up e.g buttons inside the popup (e.g the 100% width). Were these styles added to e.g harmonize with your floating editor tools, or why were they added?

2) Merely stepping with the arrows is not sufficient to trigger anything. Eg, if it says <$ it is not merely enough to arrow ones way to after to $ to fire popup. It would be nice if it were, because currently one needs to e.g insert some character and delete it to trigger the popup. Do arrow keys not fire actions like other keys?

3) The recursive macro and what it solves:
We want to test all definition tiddlers for matches, and at the end decide what to do.

I have this nagging feeling it could be made simpler than with the recursive macro by using some kind of external state value that is changed for each match. Maybe each match could append the title to a list. At the end we just extract the first title?
I actually like recursions (except their binary behaviour to fully work or absolutely not ;-) but because it is part of the wikitext I feel it is advantageous to keep it as simple as possible for others reading it. 

<:-)

Saq Imtiaz

unread,
Jul 17, 2020, 11:10:21 AM7/17/20
to TiddlyWikiDev
Hi Mat,



First, unless you object, I will hereon refer to the end user popup content templates as "popup tools" or, if the context allows, just "tools". And we can now call the /_Popup tiddler simply "the popup".


Agreed upon nomenclature is good. I struggled with this yesterday both while writing to you but also renaming macros in body/editor
 
The popup is now fully reworked. It has two groups of variables. See if you think any of them should be moved upstreams into /body/editor. It feels like the popup ought not have anything to do with the state tiddler. BTW, the editedTiddler variable refers to the viewtemplate tiddler of a tiddler being edited; in our case it'd be "RikerIpsum", and this variable is used in e.g transclude tools.

I'll have a look sometime this weekend. Perhaps targetTiddler instead of editedTiddler?
 
Changing variable names is not as obvious as I thought: The system variables should be prefixed with em-. But IMO variables that the user is in direct contact with should be as friendly as possible. For example, when he creates a popup tool I think it is better if he creates the "trigger" field as opposed to the "em-trigger" field. Yes/no?
And "fragment"... I guess it could be changed into "nameprefix" or "em-nameprefix" but I'm not sure that is more informative. It must not be "titleprefix" because it is not always titles.)

I think a user you expect to write regular expressions, can also be expected to read docs and use em-trigger instead of trigger. Personally I don't like to have any fields used in my wikis that are not namespaced unless they are extremely generic in nature, e.g. parent
 
Q's for you

1) The styling you've put in $:/plugins/EditorMagic/styles - mess up e.g buttons inside the popup (e.g the 100% width). Were these styles added to e.g harmonize with your floating editor tools, or why were they added?

Remove the stylesheet and trigger the title picker and you will understand. None of this code is influenced by the floating editor toolbar.
Having our reveal widget inside the editor means everything in the popup is inside the editor toolbar. Annoying CSS wise, but brings benefits in terms of being able to use toolbar buttons and the tm-edit-text-operation.
 
2) Merely stepping with the arrows is not sufficient to trigger anything. Eg, if it says <$ it is not merely enough to arrow ones way to after to $ to fire popup. It would be nice if it were, because currently one needs to e.g insert some character and delete it to trigger the popup. Do arrow keys not fire actions like other keys?

As you will recall from the PR and even the name of the actions attribute for the edit widget, these are inputActions. That is they fire on the input event, which is triggered when the content of the textarea changes. Arrow keys do not change the content.
I already wrote JS that resolves this some days ago, but the downside is it makes the action-popupcaret widget much less generic.
 
3) The recursive macro and what it solves:
We want to test all definition tiddlers for matches, and at the end decide what to do.

I have this nagging feeling it could be made simpler than with the recursive macro by using some kind of external state value that is changed for each match. Maybe each match could append the title to a list. At the end we just extract the first title?
I actually like recursions (except their binary behaviour to fully work or absolutely not ;-) but because it is part of the wikitext I feel it is advantageous to keep it as simple as possible for others reading it. 

Feel free to take a crack. As far as I know we don't have any other easier and efficient way to save variables for every step of a list widget run, have them persist and update, and compare them afterwards. variables set inside a list widget do not change the value of variables outside the widget. If you save the values to a field, you cannot read this again and get the updated value in the same block of actions, where block means triggered by the same triggeringWidget. In our case, that means all the actions are one block since they are all triggered by the edit widget as a result of single user interaction.

I don't see an issue with complexity here as users of the tool would not need to tinker with this, unless you don't feel comfortable enough with it to maintain the code?

Cheers,
Saq

Mat

unread,
Jul 17, 2020, 11:56:13 AM7/17/20
to TiddlyWikiDev
Saq,
 
 Perhaps targetTiddler instead of editedTiddler?

Will change.
 
 I think a user you expect to write regular expressions, can also be expected to read docs and use em-trigger instead of trigger.

:P I'll change it. 

$:/plugins/EditorMagic/styles

OK, so my point was more if I can modify the styles you added - which I now interpret as "yes".
 
Arrow keys do not change the content.
I already wrote JS that resolves this some days ago, but the downside is it makes the action-popupcaret widget much less generic.

Ah, I mistook the mere pressing of a key to be what fired the action. Anyway, could perhaps your JS be an "addon" to the action-popupcaret widget, so it doesn't modify it? Maybe if there are hooks in the widget (I'm probably using the term 'hooks' wrong).
 
 
3) The recursive macro and what it solves:
As far as I know we don't have any other easier and efficient way to save variables for every step of a list widget run, have them persist and update, and compare them afterwards.

(JS?)

I don't see an issue with complexity here as users of the tool would not need to tinker with this, unless you don't feel comfortable enough with it to maintain the code?

OK, I think it'll be fine. 

Thank you!

<:-)

Saq Imtiaz

unread,
Jul 17, 2020, 12:26:07 PM7/17/20
to TiddlyWikiDev
As far as I know we don't have any other easier and efficient way to save variables for every step of a list widget run, have them persist and update, and compare them afterwards.

(JS?)

Sure but then it would mean the detection code is in JS... which would probably lead to a more robust implementation as well. Who would write it, let alone maintain and support it? If I had the time and inclination to do that, we wouldn't have started down this road :)

Mat

unread,
Jul 18, 2020, 11:36:40 AM7/18/20
to TiddlyWikiDev
OK, so I've fiddled on with minor tweaks. Do take a look when you have time and tell if you think I should change something.

Saq Imtiaz

unread,
Jul 18, 2020, 12:31:51 PM7/18/20
to TiddlyWikiDev
@Mat looks good. Having throught about it some more, I think we should go ahead and introduce a second "content" filter for the popup tools, to remove some of the false positives.
For titles this would be something like [all[tiddlers]prefix<fragment>].....
Would also apply to widgets and macros.

Mat

unread,
Jul 18, 2020, 12:43:33 PM7/18/20
to TiddlyWikiDev
Hm, that's already in place in the tools, but maybe you mean move it from the tools upstreams into the popup tiddler?

<:-)

Saq Imtiaz

unread,
Jul 18, 2020, 12:47:15 PM7/18/20
to TiddlyWikiDev
No, I mean make that a field in the popup tool that can be accessed and used by the detection code as well. It can be an optional field if necessary.

Mat

unread,
Jul 18, 2020, 1:11:05 PM7/18/20
to TiddlyWikiDev
Aha, a field, that's an interesting idea. So this should be used both in the tools local code and in the /body/editor?

Do consider that [all[tiddlers]prefix<fragment>.. is not relevant for anything but tiddler titles though. For e.g macros, at least in the current macro picker incarnation, the macro names are "calculated" in the tool (i.e extracted by going through all $:/tags/Macro tiddlers). Basically the same for widget names. My point is that at detection code stage (presumably in /body/editor) these things are unknown, except for tiddler titles and unless we calculate everything already there or have the macro and widget lists hard coded.

...possibly the full algo to generate "the list of whatever items" could be put in a field?

<:-)

Mat

unread,
Jul 18, 2020, 1:20:17 PM7/18/20
to TiddlyWikiDev
Calling it an "algo" was a bit pretentious of me. Upon inspection, the macros are just extracted by: 

[tag[$:/tags/Macro]search[\define]get[text]splitregexp[\n]removeprefix[\define]trim[]prefix<em-fragment>]

and the widgets were indeed a static list. I did some experiments earlier to generate them dynamically from the core (which is preferable) but they are currently a plain list.

Anyway, are you saying filters like the above should be in a separate field?

<:-)

Saq Imtiaz

unread,
Jul 18, 2020, 1:22:11 PM7/18/20
to TiddlyWikiDev
I did say:

For titles this would be something like [all[tiddlers]prefix<fragment>].....

For other tools, a filter or regexp can just as easily exclude things as include. The purpose is to limit false matches. Currently a [[ or <$ will match anything after them other than a space. 

If you can't build a list of allowed values, then exclude what you know isn't allowed.

For macros, perhaps look into the variables filter operator. You still wont be able to complete macros defined in the same tiddler.

...possibly the full algo to generate "the list of whatever items" could be put in a field?


You also have to workout how to then use that code. Using a filter is as easy as using subfilter operator. 

Mat

unread,
Jul 18, 2020, 2:31:10 PM7/18/20
to TiddlyWikiDev
Initial tests fail. I posted a question here which I think describes the problem. Do take a look if you have time.

Expressed for our use case it is: putting <fragment> (now actually <em-fragment>) in a field is, as far as I find, evaluated to be nothing once the field is called into any filter.

<:-)

Saq Imtiaz

unread,
Jul 18, 2020, 3:30:33 PM7/18/20
to TiddlyWikiDev
I don't understand how the question you posted relates to what we discussed.

As I suggested earlier, a filter saved in a field can be easily re-used with the subfilter operator.

[subfilter{!!myfilter}]

You may have to make sure the em-fragment variable is defined in the detection code as well.

The tricky bit will be making sure tools without the extra filter defined still work.

If you still have problems after using subfilter, I can help but I have my hands full this weekend.

Mat

unread,
Jul 18, 2020, 5:19:57 PM7/18/20
to TiddlyWikiDev
I'm afraid I don't get [subfilter{!!em-itemfilter}] to work.
In http://editormagic2.tiddlyspot.com/ there are now two title pickers, for testing: the regular and one with em-trigger XX (and em-triggerend YY)

The regular one uses [subfilter{!!em-itemfilter}]
where that field is [all[tiddlers]prefix<em-fragment>]

The XX version uses [subfilter<em-itemfilter>] 
where the variable is defined in the popup as <$wikify name=em-itemfilter text={{!!em-itemfilter}}>

...but neither works. It seems that once it gets into the subfilter it becomes [all[tiddlers]prefix] i.e the <em-fragment> is lost.


You write:
You may have to make sure the em-fragment variable is defined in the detection code as well.

...but that can't be a problem for the above, right?, since reinstating the filter from the field into the code is how it was previously when the filter worked.

When you have time, please take a look - no rush, of course. Maybe I am using subfilter the wrong way but I don't think so...

Thank you!

<:-)
 

Saq Imtiaz

unread,
Jul 18, 2020, 5:43:22 PM7/18/20
to TiddlyWikiDev
I only have access to a phone at the moment and your editor gets in the way.

Go through your code stepwise in the popup tool and make sure you aren't accidentally settings currentTiddler to a different variable.

As long as currentTiddler points to the popup tool tiddler this will work:

[subfilter{!!em-itemfilter}]

Mat

unread,
Jul 18, 2020, 6:08:21 PM7/18/20
to TiddlyWikiDev
Yes the filter now works! (The problem were due to a totally other mistake on my side that surprisingly had not shown effects previously.)  
I'll get to the detection filter testing tomorrow. Head is too slow now.

<:-)

Mat

unread,
Jul 19, 2020, 7:21:35 AM7/19/20
to TiddlyWikiDev
@Saq

OK... I can't tell if I'm on the right way. I might be. Typing e.g [[Edito shows populated popup as intended. Typing in e.g [[asdf seems to erroneously trigger the popup (i.e showing the artifact) but then leaves it hanging at a static position as one types the second letter and onwards. But if [[asdf is left there and focus is changed to elsewhere and one returns to continue typing e.g [[asdfxxxx then there is no recurrence of the popup.

I'm thinking this might be correct behaviour and that the very initial firing, giving cause to the empty popup, is because of a first and single call to emptyMessage=<<em-checkNextTrigger>> and then the artifact lingers because... I dunno... because there is no other instruction?

...and that might also be what causes this: If you type [[Edi]] the (full) popup lingers in spite of the closing brackets. And if typing e.g [[asdf << then the macro popup does not show.

Could you give it a test? http://editormagic2.tiddlyspot.com/

Yes, the current code inelegantly has two repeated blocks; one for has[em-itemfilter] and one for !has[em-itemfilter].
Also, only TitlePicker has the itemfilter so far.

For showing diffs, is gh the only way?

<:-)

Saq Imtiaz

unread,
Jul 20, 2020, 4:45:16 AM7/20/20
to TiddlyWikiDev
@Mat there are a lot of tools for showing diffs, but the advantage with a version control system like git is that it keeps track of the different versions that you might want to see diffs between, and github also provides a nice UI for viewing diffs. Otherwise its considerably more work, find the two different versions to compare, manually generate a diff, etc...

On that note, I am going to need the latest working copy of the demo to be able to compare and generate a diff. 

I assume that would include (starting with what I last worked on) your renaming of variables and macros, plus introduction of em-filter in popuptools, with body/editor untouched.

Mat

unread,
Jul 20, 2020, 5:53:09 AM7/20/20
to TiddlyWikiDev
I am going to need the latest working copy of the demo to be able to compare and generate a diff. 

By "working" I assume you mean the latest copy that I'm hoping you take a look at; yes that is http://editormagic2.tiddlyspot.com/ 
 
I assume that would include (starting with what I last worked on) your renaming of variables and macros, plus introduction of em-filter in popuptools, with body/editor untouched.

* Yes, I renamed most variables and macros - but I expect you to not agree with everything. For one thing, I'm not fully sure about the necessity to em- prefix very internal/local variables. But maybe everything should be prefixed. I've been a bit inconsistent. 
* em-filter in popup tools; so far only TitlePicker has it and once it works properly with that I'll do the others
* body/editor I did have to touch, as per the following diff-images (sorry):














Saq Imtiaz

unread,
Jul 20, 2020, 6:30:47 AM7/20/20
to TiddlyWikiDev
@Mat


On Monday, July 20, 2020 at 11:53:09 AM UTC+2, Mat wrote:
I am going to need the latest working copy of the demo to be able to compare and generate a diff. 

By "working" I assume you mean the latest copy that I'm hoping you take a look at; yes that is http://editormagic2.tiddlyspot.com/ 

No I mean the latest version where everything worked as it should. I assume there was a time where you had renamed variables, and introduced em-filter in popuptools but not yet in body/editor... and everything was working as it should. That's the file I would like a copy of.
 
The diff is helpful, but I want to use the "before" code from the diff as a starting point, and don't want to type it all out by hand copying from the image :)

Saq

Mat

unread,
Jul 20, 2020, 6:58:33 AM7/20/20
to TiddlyWikiDev
No I mean the latest version where everything worked as it should. I assume there was a time where you had renamed variables, and introduced em-filter in popuptools but not yet in body/editor... and everything was working as it should. That's the file I would like a copy of.

I'll make a new version fulfilling this as good as I can. (If I recall, I found that I had to make modifications to body/editor because there were dependencies but I'll see what I can do.) I'll get to this right away.

<:-)


It is loading more messages.
0 new messages