How to implement an NSTextView that performs on-the-fly markup to RTF conversions - objective-c

I'm trying to build an NSTextView that can take "marked up" input that is automatically translated into beautiful RTF-style text while the user types.
The idea is to let the user enter text in "plain text" format, but to "beautify" it on the spot, e.g.
H1 A quick list:
* first item
* second item
would be translated into a first line with a header font, followed by a bulleted list.
I have found plenty of potential ways of doing this, but the Text System is incredibly complicated (with reason) and I don't want to start "cooking my own" if there is already something suitable built-in. BTW I would be happy with a Snow Leopard only API.
The first thing I thought of was "data detectors", but I can't find a public API for doing this.
Having reached the end of the road with that, I turned to the new "Text Input Sources API". This does all kinds of things, but the "data-driven input methods" section of the WWDC 2006 presentation "Take Charge of the Text Input" seems interesting in my context. Beyond that single presentation slide however nothing seems to exist anywhere, so it's a bit of a dead end again.
Finally, I had a look at the NSSpellChecker class which is also supposed to offer completion features and automatic corrections.. but I'm not sure how this could be re-purposed for my requirements either.
At the moment, I'm tempted to just re-parse the entire NSTextStorage manually and make the changes myself when the user stops typing.. but I'm sure there are cleverer heads around this forum..
Any advice or pointers in the right direction would be greatly appreciated.

Neither data detectors nor the spell checker are appropriate for this task. Assuming you're just looking for a way to pass the input to a parser/formatter you already have, interfacing with the text system isn't too difficult. You're on the right track with handling the editing to NSTextStorage.
Along those lines, there's no need to re-parse the entire thing when the user stops. The text system sends you the modified range and gives you the opportunity to act on those changes (and even reject them out of hand). Since all changes funnel through this (typing, pasting, dropping...), this is the point where you want to intercede.
Because you're dealing with headings and bulleted lists, I'd get the enclosing paragraph of the modified range. This gives you a nice, round unit of work that is easily discovered and perfectly fits what you're trying to accomplish.
Good luck!

Related

Intellij IDEA SDK - How can I programmatically handle spellcheck 'typos'?

Wrote a plugin to handle some custom format stuff in yaml files that I've written for a huge project. It's a chat bot that can respond in a huge number of ways. There is a lot of slang and non-standard words in the yaml.
I don't want to disable spellchecking as I want to fix legitimate speeling errors. But the annotations under the "misspelled" slang words are conflicting with the annotations in my plugin, and causing issue.
One yaml file has 349 "typos". 10% or so are legit. The rest are slang and custom words.
I need to do one of two things. Either add those words to the dictionary (I've found the method to do that - SpellCheckManager.getInstance(project).acceptWordAsCorrect()) OR get a list of the words and create a custom dictionary from them. Both approaches require me to grab a list of all typos in the document/editor/project.
That's the part I can't find. Looked everywhere. (List of current Annotations? List of current Problems?) Googled my fingers off. Anyone able to point me in the right direction?
This is not the IDEAL solution, but it worked for my means, and I'm leaving the answer in case this is googled.
In DaemonCodeAnalyzerImpl, there is a method:
DaemonCodeAnalyzerImpl.getHighlights(Document document, HighlightSeverity minSeverity, Project project);
This returns a list of all highlights in the document. The method is Annotated with #TestOnly, and docs state that it should only be used in Test code because it breaks/shortcuts the normal way to access that. It still works in non-test code however.
Since the only thing I wanted was the strings of the typos, I pulled the list, then looped through the HighlightInfo's in the list, and pulled the .getText()s.
No danger of screwing anything up.
Then pushed all those strings into:
SpellCheckerManager.getInstance(project).acceptWordAsCorrect(word, project);
Viola! All current highlighted typos are now added to the dictionary.
Proper solution? No. Good enough for what I needed to accomplish? Yup.

Intelij extract method keeps trying to replace duplicate method signatures - please stop

Intellij has a really neat feature, that lets me seamlessly extract a block of code into its own method. I can then give this method a nice, descriptive name and move on with life.
However, intellij also tries to find other blocks of code that are similar, and then tries to perusade me that I should also refactor them too, to use this new method its made. And then, when I hit the oddly-named "cancel" button (which implies the whole operation is cancelled, but it's not, it just stops asking about any remaining blocks), it leaves me looking at whatever the block of code it last asked me about.
I really don't like this feature. Here's why: If I'm say comparing two ints - the naming of the code block will depend on the context of those two ints, but intellij will find any comparison between two ints anywhere in that file, and then insist that this is also a candidate for extraction.
Most times it is not, and to make it worse, when I ask intellij to stop it, in a fit of pique, leaves me wherever the last comparison was, so now I have to navigate back to where I was working.
How do I tell intellij just to extract exactly what I selected, and do nothing else?
Please follow/vote/comment the issue created for this usability problem at YouTrack:
https://youtrack.jetbrains.com/issue/IDEA-233201

custom soft wrap in intellij?

it bothers me:
why can't i "soft return" in intellij (or any IDE actually)?
is there a way i don't know of to "X + return key"?
situation: i want to copy&paste long paragraphs into a translation.json.
Afterwards, i want to format them with html tags.
So why can't i have
"translation": {
Hi!/
this is/
the text./
maybe there is a/
LINK too?/
/
Second Paragraph/
/
This is the second paragraph./
}
with /being soft wrap markers
instead of
"translation": {
Hi! this is the text. maybe there is a LINK too? Second Paragraph This is the /
second paragraph.
}
(it makes inserting the html tags a PITA)
why can't i "soft return" in intellij (or any IDE actually)?
Most likely because it is not a highly desired feature. Secondly, from a practical standpoint, the implementation would be cumbersome because most file formats an IDE uses are ultimately plain text. As such the file does not have a concept of a soft return. For an IDE to support arbitrary soft returns, it would need to maintain a data store containing the metadata of where in each and every file you've ever edited you want soft returns.
Or alternatively, the soft returns would need to be stored in the file. But the only way to do that and not "effect" the actual code in the file is via comments. Such as how an IDE uses comments to suppress warnings, create an arbitrary folded block, or turn off auto formatting. (And of course, with your example, JSON does not have comments, further complicating things.) Using comments for soft returns would, I think, result in a lot of clutter in the file. For example, for HTML, even using a one character comment of a paragraph symbol "¶" results in a lot of clutter:
"translation": {
Hi!<!--¶-->
this is<!--¶-->
the text.<!--¶-->
maybe there is a<!--¶-->
LINK too?<!--¶-->
<!--¶-->
Second Paragraph<!--¶-->
<!--¶-->
This is the second paragraph.<!--¶-->
}
You could always request a new feature to add support for something like this to IDEA, but I'm fairly sure it would unlikely gain any traction (based on 13+ years of IDEA usage and very active community membership).
I agree with #Peter's comment that more detail about the workflow you have might help. Ultimately, the Paste as plain text action he mentions is likely the solution. Or you can turn off reformatting on paste in Settings > Editor > General > Smart Keys > "Reformat on paste". See the following help page for more information: https://www.jetbrains.com/help/idea/2016.2/smart-keys.html

On Smalltalk IDEs (Squeak, VisualWorks, etc), how can you navigate away from a message's code you're working on to inspect another?

In every IDE I've tried so far, if I'm partway through writing a message and need to look at the code of another, the browser asks me if I want to save. But if I say I do want to save, it actually tries to compile/syntax check the code, and refuses to perform the save if it does not pass. The only way to view the source of another message seems to be to say "no" to save and have everything wiped. How can I look at another class incidentally, or save code I am partway through working on that might not build right now?
Smalltalk is a multi-browser system. You'll need to have lots of different browsers open. Smalltalk is opinionated. The system browser (Nautilus) doesn't make it easy to view long methods, steering you towards writing short ones. It doesn't make it easy to have non-compiling code in a method, to steer you towards making small changes.
Experimental/prototypical code you might want to have in a Workspace/Playground. That can save to disk.
We are aware that it is an issue for people new to Smalltalk. We tried some fixes, they were a lot worse.
For now there is no easy way to do that. The two easiest opting are
Make the current method syntactically correct and save it.
Open another browser. If you want to see a class or method that is in your current code, you can cmd+click it or use "browse it", "implementors of", shortcuts that will open another window.
Also in pharo you can use GTSpotter to quickly find what you are looking for and preview its source code
When you say "this seems like a pretty huge thing to be missing,
and it could be gotten around by just having the option to use
a regular editor" I'm afraid you've entirely missed the point.
Understandable, though -- happens to us all.
Or did. Perhaps it was long ago, but we
were all there.
You might be thinking about the task in terms of
scrolling a giant text up and down to find what
you want. Scroll up -- read a little -- scroll back --
and continue making your changes.
And when you say " I can't imagine any circumstance
where it is OK, in pursuit of any agenda, to throw away
the coder's work against their will "
you are spot on correct, of course.
Imagine -- scrolling around, making dozens of little changes,
and before you've saved them -- poof -- they're all thrown away --
a mistake, perhaps, but completely against your will.
That would be awful. We're agreed.
(In fact, the editor I'm using to type this
is like that -- I can scroll around the whole thing,
making little improvements, all over, but it could
all go --poof-- and disappear, All of it.
Fairly common occurrence, when editing the web.
)
So let's try another run through that same task.
You get one little teensy, DUMB AS A POST editor,
where you can only see one thing at a time.
And now you just want to scroll somewhere else,
for a moment, and come right back.
Which actually means that
you are attempting to look up a second method,
while already changing a first method
(which would require the browser toforget the
context of the first method, and move to the second).
The browser does not know how long you will be away
from this context. You might go chaining along from
place to place, stop and read an email, take a call,
and go to lunch.
So, the browser cautions
"Hey - want to save this first?"
as if to say:
"
Hey - I can't imagine any circumstance where it is OK,
in pursuit of any agenda, to throw away the coder's work
against their will.
So listen up, coder.
You want to save this first?
"
But you can't save it.
You must first look something up.
Conundrum.
Ah-ha! There is a list of methods in that other pane.
One of them is highlighted.
Not those -- that one.
Double click that one.
The one you're already in.
As if to say
" Thanks. Good catch.
Yes, I know - can't though.
I need to change contexts.
You stay right here.
And give me another context
to go wandering about in.
please.
"
Soon, I expect, they'll start actually talking.

Excel, create an automatic save/change log, how to?

I teach at a university and one assignment i have developed tests some quite specific modelling skill sets in Excel. Because of this, and because all assignments need to be fairly weighted, they end up having largely the same content (in terms of the final code) with different variables so that they are not exact copies - so it is fairly easy for students to take another persons completed file and input their own variables, change a few cosmetic items (drag data locations, colours, borders etc) and hand the work in as their own. i am confident that this is occurring and most of the time i can identify the suspects easily but proving the collusion (not so much detecting it), this is difficult.
I am trying to work out how i can include somewhere on the worksheet (which i will provide as a template) a function that logs the user ID and time each incidence that the save button is pressed (or at a set interval)? This way i can have this info logged in the background (hopefully where nobody can find or goes looking for it) and it will be quite easy for me to see if at any point along the way the student working on the sheet changed - indicating collusion. Of course there are other ways around this, and i am not looking for a fail safe system, just an easy way to catch lazy cheats.
I can find functions that save the last user to a cell, but none that can provide an ongoing log. Ideally, i would like it to be as covert as possible, i.e., avoiding obvious macros would be handy but i can understand this might be a problem. Does anyone have any tricks up their sleeve to help me in my quest to wipe out student copying?
Type sign in Excel's help. Look at digital signatures. There may be some way of using them?
From Help
After you have installed your digital certificate, you can sign files and macro projects.
When you digitally sign a file, you certify that the information in the file is valid and that it has not been modified since the file was signed. As long as a file is unchanged, reviewers can attach signatures to it. You might use a digital signature with important files. When you digitally sign a macro project, your digital signature says that you guarantee that the project is safe. Just as signed files remain signed until the file is modified, signed macro projects remain signed until the macro code is altered.
Or perhaps turn on track changes and make an initial change yourself.