Seems like it ought to be possible with ANSI sequences, but I haven't been able to make it work. Vincent?
It would be pretty easy in a plugin. A plugin key handler is passed a structure containing the command line and the cursor position, which it can modify at will.
I doubt CONHOST will act on ANSI sequences in the input (or maybe even know about them). Even if it did, TCC wouldn't know about it and KEYINFO's idea of the current position will be incorrect.
And I'm not sure how easy/hard it'd be in a plugin. If you were going to do it anywhere except the end of a command line, I suppose the plugin would have to check for insert/overstrike and act accordingly.
I used to have some keystroke aliases that included cursor movement.
I assigned control characters to line editing commands, in: OPTION | Keyboard | Category: Editing
The assignments appeared in in TCMD.INI under [Keys], for example: BeginLine = Home Ctrl-Q
EndLine = End Ctrl-T
Left = Left Ctrl-U
In versions from the distant past you could include those control characters literally in aliases, and when executing those aliases, TCC would interpret the control characters according to those assignments. Sadly, that doesn't work any more: TCC now enters the control characters into the command literally.
I'm in INSERT mode everywhere. When I type @FUNCTIONs names (command line or editing a BTM) I almost always type both brackets and a <Left>. That helps keep track of things if the line is long and (especially) if there are nested functions.
How about this: Typing an open bracket or an open parenthesis automatically inserts the matching close mark to the right of the cursor? Something like that would be trivial to implement.
How about this: Typing an open bracket or an open parenthesis automatically inserts the matching close mark to the right of the cursor? Something like that would be trivial to implement.
Won't it be tedious if not at the end of the command line (dealing with insert/overstrike mode as needed)? And if end of command line is required, that will preclude building nested thingies from the outside in.
If I'm missing something and it really would be trivial, you could do the same for double quotes, backticks, and braces.
Won't it be tedious if not at the end of the command line (dealing with insert/overstrike mode as needed)? And if end of command line is required, that will preclude building nested thingies from the outside in.
If I'm missing something and it really would be trivial, you could do the same for double quotes, backticks, and braces.
I think we can safely ignore overstrike mode. Anyone who uses overstrike by default would not use such a feature in the first place. ("Please automatically supply a close bracket, so I can overwrite it with my next keystroke"?)
I'm attaching a ditzy demo plugin, with no documentation. There is almost nothing to it, though I did add a check for overstrike mode so you can see the doomed punctuation mark for the fraction of a second before you hit the next key.
Whether this feature would actually be useful to anyone is open to question.
Autobrackets ... interesting ... simple ... and it works I've started one that will use SendInput (letting TCC worry about the tail). If I'm still so inclined after dinner, I'll get back to it.
Autobrackets ... interesting ... simple ... and it works I've started one that will use SendInput (letting TCC worry about the tail). If I'm still so inclined after dinner, I'll get back to it.
That was going to be too hard. So I did it as you did, Charles. And, I did it for all of these (below). I'll just leave it in place and see if it enhances my life.
I'm a bit leery of quotes because the open quote and the close quote are the same character. If you want to determine whether the quote the user typed is an opener or a closer, you have to look at the context.
I'm thinking maybe: If the user typed a quote, look at the previous character. If it's whitespace, or a colon, equals sign, or open bracket, or if you're at the start of the line (there is no previous character), then it's an opener and should be closed. Anything else, ignore it. Does that make sense to you? Too simpleminded?
I'm a bit leery of quotes because the open quote and the close quote are the same character. If you want to determine whether the quote the user typed is an opener or a closer, you have to look at the context.
I'm thinking maybe: If the user typed a quote, look at the previous character. If it's whitespace, or a colon, equals sign, or open bracket, or if you're at the start of the line (there is no previous character), then it's an opener and should be closed. Anything else, ignore it. Does that make sense to you? Too simpleminded?
I haven't programmed in a while so I'm enjoying fooling around. I don't get to use the comma operator often; when I do I feel good about it. This has got to be at least a little more efficient that a counted loop and an array of open/close pairs.
So let me check my understanding. You're assigning a value to c for each comparison. But if the comparison is true, it short-circuits any remaining comparisons, and therefore any further assignments. The last assignment was done by the first (only) comparison which returned true.
And if none are true, then you've done six (wrong) assignments, but it doesn't matter because c is only used if one of your comparisons was true?
Yup, that's how it works. It's certainly no worse than a counted loop (where you keep incrementing a counter, possibly for no good reason). The only reason I think it might be more efficient is that in evaluating ( lpki->nKey == oc[n] ) (vs. lpki->nKey == constant) is that you've got to add to the oc pointer each time).
Maybe I'm missing something, but I think you need to add a null to the new end of your string. It looks like you're moving everything up one place, with the last non-null character overwriting the original null.
Hmmm! It works. And putting in some comments made me feel pretty good about it. Here it is again with a few comments.
Code:
VOID AddCloser(LPKEYINFO lpki, WCHAR closer)
{
WCHAR *p = lpki->pszCurrent;
// this loop will stop when *p == 0 (and p will be incremented)
while ( *p++ != UNICODE_NULL );
// now p points one past the terminating null
while ( p > lpki->pszCurrent )
{
*p = *(p-1); // move each character one to the right (starting with the terminating null)
p -= 1;
}
// insert the closer
*p = closer;
}
Yours looks good. I'm finding the end whereas you get it with wcslen() (pretty much the same thing).
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.