Hello all,
I'm writing a command to mimic eclipse's semicolon insertion. In Eclipse, when you press ';' it looks for a semicolon at the end of the line; if there is one already there, you get a ';' at your cursor (as if you had typed it normally); if not, it puts it in the proper position at the end of the line, and your cursor is at the end of the line.
With the following command, TextMate will put the semicolons in the desired place, but the cursor doesn't move, which is annoying.
input: selected text or line output: replace selected text activation: key equivalent ';' scope: "source"
#!/usr/bin/env ruby
$t = STDIN.read
if $t =~ /\A(.*);\Z/ $c = ENV['TM_LINE_INDEX'].to_i print $t.insert($c, ';') else print $t+';' end
Any idea how to move the cursor? Snippets handle cursor motion, but I'm not sure I can get the semicolon to go to the right spot. Ideas? Tricks?
Best, Kevin
With the following command, TextMate will put the semicolons in the desired place, but the cursor doesn't move, which is annoying.
input: selected text or line output: replace selected text activation: key equivalent ';' scope: "source"
#!/usr/bin/env ruby
$t = STDIN.read
if $t =~ /\A(.*);\Z/ $c = ENV['TM_LINE_INDEX'].to_i print $t.insert($c, ';') else print $t+';' end
Any idea how to move the cursor? Snippets handle cursor motion, but I'm not sure I can get the semicolon to go to the right spot. Ideas? Tricks?
Nop. It should be great to have an API to access TM interface from the scripts, shouldn't be?
;)
Juan <juanfc@...> writes:
Nop. It should be great to have an API to access TM interface from the scripts, shouldn't be?
;)
Hi there,
I really don't mean to sound like a jerk. But your continuing to say this (I think this is the 5th email about it, in addition to at least one ticket) is just getting annoying. A couple of comments:
1. Allan already knows that there are things which require hooks into other parts of the application, and cannot therefore be done currently without a plugin.
2. If we examine this state of affairs logically, and try to figure out *why* it might be the case, we find the following possibilities.
* It's possible there are other areas of the application he feels are more essential. In this case, continually repeating "API, API, API" just distracts him from these other features, preventing him from ever getting to work on the API you want.
* It's possible that Allan doesn't like giving bundle items such general power. Maybe he feels that we'd end up with a system of commands that looks like emacs, which is arcane and vastly more complicated than TextMate's (more effective, and more *usefully* flexible) extension mechanisms. In this case whining just makes Allan annoyed, without increasing your chances.
* It's possible that Allan hasn't decided how he wants to present such increased functionality to users. For instance, allowing conditinals and loops inside macros is the only thing technically needed to have the power you are requesting. But such additions aren't easy to create. And often the behaviors of such complex macros would be better handled by a command anyway. In this case, given that you haven't given any concrete suggestions, you're just distracting from these deliberations.
3. Now let's consider from the point of view of other readers on this mailing list. Such a reader has nothing to gain from the continual pleas for an API. Those pleas are just earning you ill will, and taking time to skim over by list readers. They don't have any concrete suggestions, or any actual thwarted use cases. They aren't solving anyone's problems, or making anyone think.
4. To add insult to injury, in this particular case, your answer was in fact wrong. The OP's question was perfectly answered by Haris, who noted that the only required action was ticking a single checkbox. So this specific example, if anything, proves that an API is not needed, because existing structures suffice.
Conclusion: find something more productive to do, like making some useful language grammars or commands, or else go back to Alpha or emacs or whatever, where you can get all the API you can eat. When you have read the manual, and spent a few weeks or months working with TextMate, and you find something you can't accomplish, send a note to this list, and we will try to help you. If your problem still cannot be solved, and its solution will vastly improve the productivity of a large number of people, then you will have a more compelling case to make for the addition of an API.
-Jacob
El 13/02/2007, a las 22:30, Jacob Rus escribió:
Conclusion: find something more productive to do, like making some useful language grammars or commands, or else go back to Alpha or emacs or whatever, where you can get all the API you can eat. When you have read the manual, and spent a few weeks or months working with TextMate, and you find something you can't accomplish, send a note to this list, and we will try to help you. If your problem still cannot be solved, and its solution will vastly improve the productivity of a large number of people, then you will have a more compelling case to make for the addition of an API.
There are so many things that cannot be done without the use of an API that your suggestion is absolutely unworkable.
1) I did the suggestion not only to this list but also to Allan. He answered me. It was ok.
2) I was trying to answer Kevin about a question he issued but I was cheeky. Obviously there is one way to position the text analyzing the text and placing there $0 and outputting through as snippet. This was the correct answer to Kevin. And as I learned a lot with the Charilaos answer I payed him my gratitude.
3) You are asking for improvements in the way TM do the things _now_ but I am telling you that many things are absolutely impossible without a lot of work from the programmer side. An simple example: to select the text that is inside html/xml "braces" <font ...> </ font>. This is very important in html editing for many reasons and is absolutely impossible in TM right now.
On 2/13/07, Juan juanfc@lcc.uma.es wrote:
I am telling you that many things are absolutely impossible without a lot of work from the programmer side.
Juan,
you are fighting the wrong fight.
I totally agree on all of Jacob's points, and would ask you to please relax.
"Impossible" is a lot easier to solve with an open mind ;)
An simple example: to select the text that is inside html/xml "braces" <font ...> </ font>. This is very important in html editing for many reasons and is absolutely impossible in TM right now.
Have you, by any chance, taken a look at the documentation?
All you need is a proper scope and CTRL + Option + B (Select Current Scope)
There may be other possibilities ("There's more than one way to do it"). In my experience, "naive" approaches work better in TextMate.
Now please read Jacob's response again, with an open mind, and try to calm down and not be a bitch. There's people working in here.
-- Ale Muñoz http://sofanaranja.com http://bomberstudios.com
Thanks Ale
only one thing. That not was the point.
The point it is impossible to build a recursive scope in HTML. In HTML, for example, if your are inside a nested tag and you press ^- Opt-B one time, to times, three times, etc, you will get _all_ your source selected. Never at the third (etc) level out in the nesting. I like a lot TM, I can assure you, for many reasons. But I don't understand why the main problems are so tabued.
El 14/02/2007, a las 1:27, Ale Muñoz escribió:
On 2/13/07, Juan juanfc@lcc.uma.es wrote:
I am telling you that many things are absolutely impossible without a lot of work from the programmer side.
Juan,
you are fighting the wrong fight.
I totally agree on all of Jacob's points, and would ask you to please relax.
"Impossible" is a lot easier to solve with an open mind ;)
An simple example: to select the text that is inside html/xml "braces" <font ...> </ font>. This is very important in html editing for many reasons and is absolutely impossible in TM right now.
Have you, by any chance, taken a look at the documentation?
All you need is a proper scope and CTRL + Option + B (Select Current Scope)
There may be other possibilities ("There's more than one way to do it"). In my experience, "naive" approaches work better in TextMate.
Now please read Jacob's response again, with an open mind, and try to calm down and not be a bitch. There's people working in here.
On Feb 13, 2007, at 7:52 PM, Juan wrote:
Thanks Ale
only one thing. That not was the point.
The point it is impossible to build a recursive scope in HTML. In HTML, for example, if your are inside a nested tag and you press ^- Opt-B one time, to times, three times, etc, you will get _all_ your source selected. Never at the third (etc) level out in the nesting. I like a lot TM, I can assure you, for many reasons. But I don't understand why the main problems are so tabued.
This might be relevant for the HTML stuff: http://subtlegradient.com/ articles/2006/02/05/my_textmate_bundles_etc
As for your last question, it is not that we are not willing to discuss particular questions about how TM could be improved, it's that we don't agree with what you consider to be the only answer to them. Your repeating API,API,API is not helping. TextMate has gained such popularity in two years exactly because it is doing things in a novel way. Just repeating what other editors have done is not necessarily the right way about it, unless it is backed up by enough examples that should be done that would benefit the user, and an understanding of whether these things can be done in TM or not at this point.
As Jacob already suggested, here is how a productive conversation would go:
1) Think of a particular task you'd like to do, that TM seems to your eyes not to be able to do. 2) Read TM's documentation to make sure you understand what TM can and cannot do with Snippets, Commands, Macros and Scope Selectors. 3) Bring the question up in the list, asking how one could do this in TM. 4) If we can't come up with a reasonable way, then we can start asking about whether this is something that would really boost the user's productivity, and what the best way for TM to add it would be. At this point, finding the correct abstraction would be necessary. 5) It might end up, after discussion, that perhaps there are other ways around what you were trying to do, that would benefit the user more.
Haris
P.S. As for your question about nested scopes, there is a chance you could go quite a long with with subtlegradient's commands that I linked to above. A lot of this can be accomplished by a simple find macro recording. It is still probably not perfect, and Allan is aware of this, I've bugged him about it as well, nested scopes appear a lot in LaTeX where I live. The question is what the best way about improving it is, and of course a better HTML language grammar would be a good start, at the moment it doesn't even distinguish between different tags.
I can't resist making a, possibly bad, metaphor: You wouldn't get a Porsche simply because you need to get to the grocery store in less than 10 minutes. First of all, it's a bit of an overkill, and second of all it doesn't have enough room for the groceries, it wasn't made for grocery-shopping.
In other words, let's find the right answer. API is not it, it only has three letters.
On 14. Feb 2007, at 01:52, Juan wrote:
The point it is impossible to build a recursive scope in HTML. In HTML, for example, if your are inside a nested tag and you press ^- Opt-B one time, to times, three times, etc, you will get _all_ your source selected. Never at the third (etc) level out in the nesting.
That has to do with how the grammar has been made, i.e. it does not mark up a tag pair as its own element, and thus cannot be selected via ⌃⌥B -- something we do consider improving (in the HTML grammar). At least it will be updated for the 2.0 grammar features.
I like a lot TM, I can assure you, for many reasons. But I don't understand why the main problems are so tabued.
They are not -- but you seem to have just the one goal of repeating the need for an API, but without being concrete in what you need from it.
The need for an API has already been acknowledged, but there are a lot of considerations before opening up the innards of TM. Embedding a Ruby interpreter and implementing a carbon copy of Alpha’s API (as what seems to be your suggestion) is certainly not how I want to tackle it.
You also overlook the power of declarative abstractions, which is one of the fundamental advantages in TM. Solving problems with code is often counterproductive to finding new and better abstractions, and the abstractions, when done right, buys you much more long-term.
Example: TextMate uses a declarative system for language grammars, some people have pointed out limitations in this system which would not exist if each bundle author could just write his own parser. But if you look at how many languages TM support, and how good it actually does support them, you should find that TM generally does a *much* better job than competing editors with binary parsers -- not only that, but because everything is declarative, one grammar can easily include another, and 2.0 will be able to use existing grammars for completely new features, like the scope injection mentioned on this list. This would be *completely* impossible, had each bundle author written his language parser as code.
So there is no taboo -- when people are not jumping on the bandwagon it is likely because they do not think that it is as serious a problem as you make it out to be. Adding an API gives us a little more power, adding new abstractions (like attributes and dynamic scopes) will give us a lot! Did HTML gain the most from CSS or JavaScript? While they are different things for different purposes, the CSS abstraction IMO added immensely more value to crafting web pages.
Another thing I should mention: The way you open up a Mac application for scripting is via the Open Scripting Architecture, yes, AppleScript is slow and just plain sucks. But wait, isn’t there a lot of rumors about RubyOSA, PyObjC, etc. being included in Leopard? Maybe we should hold off embedding that Ruby interpreter, and see if using the platform-recommended way will not give us more long-term advantages ;)
DISCLAIMER: Don’t read too much into the above, I am still evaluating.
I've loved Textmate for a while now, but reading this email I grokked something new about it and love it twice as much now.
This really highlights the benefit of having a BDFL. Someone who can see the very, very wide picture and force you to do something you might not want to in order that the whole community can benefit.
An API would let you solve small problems quickly and would benefit individuals, and sometimes small groups, in the short term. It's often irritating not to just be able to solve them immediately in a hackish way.
Allan's system is working towards solving the general problem of writing code, forcing us to think more about what is needed for all languages in general, and creating new abstractions.
I actually think providing an API would be damaging to the Textmate community in the long term. If something more is needed then we need to improve the abstractions (as Allan is doing and is apparently coming).
Ed
On 14/02/07, Allan Odgaard throw-away-1@macromates.com wrote:
On 14. Feb 2007, at 01:52, Juan wrote:
The point it is impossible to build a recursive scope in HTML. In HTML, for example, if your are inside a nested tag and you press ^- Opt-B one time, to times, three times, etc, you will get _all_ your source selected. Never at the third (etc) level out in the nesting.
That has to do with how the grammar has been made, i.e. it does not mark up a tag pair as its own element, and thus cannot be selected via ⌃⌥B -- something we do consider improving (in the HTML grammar). At least it will be updated for the 2.0 grammar features.
I like a lot TM, I can assure you, for many reasons. But I don't understand why the main problems are so tabued.
They are not -- but you seem to have just the one goal of repeating the need for an API, but without being concrete in what you need from it.
The need for an API has already been acknowledged, but there are a lot of considerations before opening up the innards of TM. Embedding a Ruby interpreter and implementing a carbon copy of Alpha's API (as what seems to be your suggestion) is certainly not how I want to tackle it.
You also overlook the power of declarative abstractions, which is one of the fundamental advantages in TM. Solving problems with code is often counterproductive to finding new and better abstractions, and the abstractions, when done right, buys you much more long-term.
Example: TextMate uses a declarative system for language grammars, some people have pointed out limitations in this system which would not exist if each bundle author could just write his own parser. But if you look at how many languages TM support, and how good it actually does support them, you should find that TM generally does a *much* better job than competing editors with binary parsers -- not only that, but because everything is declarative, one grammar can easily include another, and 2.0 will be able to use existing grammars for completely new features, like the scope injection mentioned on this list. This would be *completely* impossible, had each bundle author written his language parser as code.
So there is no taboo -- when people are not jumping on the bandwagon it is likely because they do not think that it is as serious a problem as you make it out to be. Adding an API gives us a little more power, adding new abstractions (like attributes and dynamic scopes) will give us a lot! Did HTML gain the most from CSS or JavaScript? While they are different things for different purposes, the CSS abstraction IMO added immensely more value to crafting web pages.
Another thing I should mention: The way you open up a Mac application for scripting is via the Open Scripting Architecture, yes, AppleScript is slow and just plain sucks. But wait, isn't there a lot of rumors about RubyOSA, PyObjC, etc. being included in Leopard? Maybe we should hold off embedding that Ruby interpreter, and see if using the platform-recommended way will not give us more long-term advantages ;)
DISCLAIMER: Don't read too much into the above, I am still evaluating.
For new threads USE THIS: textmate@lists.macromates.com (threading gets destroyed and the universe will collapse if you don't) http://lists.macromates.com/mailman/listinfo/textmate
On Feb 13, 2007, at 2:16 PM, Kevin Cox wrote:
Hello all,
input: selected text or line output: replace selected text activation: key equivalent ';' scope: "source"
#!/usr/bin/env ruby
$t = STDIN.read
if $t =~ /\A(.*);\Z/ $c = ENV['TM_LINE_INDEX'].to_i print $t.insert($c, ';') else print $t+';' end
Any idea how to move the cursor? Snippets handle cursor motion, but I'm not sure I can get the semicolon to go to the right spot. Ideas? Tricks?
Set your output to Insert as snippet. This will actually replace whatever the input is, but will interpret the output as a snippet. Then you do the processing of the line, and you snippet-escape the result, and add $0 at the location where you want the caret to end up. The library escape.rb will be of help to you, it contains an "e_sn" command that escapes the text for use in a snippet.
Best, Kevin
Haris
Wow. Thanks so much!
If anybody's interested, here's the finished source:
#!/usr/bin/env ruby
$t = STDIN.read
if $t =~ /\A(.*);\Z/ $c = ENV['TM_LINE_INDEX'].to_i print $t.insert($c, ';$0') else print $t+';$0' end
On 2/13/07, Charilaos Skiadas skiadas@hanover.edu wrote:
On Feb 13, 2007, at 2:16 PM, Kevin Cox wrote:
Hello all,
input: selected text or line output: replace selected text activation: key equivalent ';' scope: "source"
#!/usr/bin/env ruby
$t = STDIN.read
if $t =~ /\A(.*);\Z/ $c = ENV['TM_LINE_INDEX'].to_i print $t.insert($c, ';') else print $t+';' end
Any idea how to move the cursor? Snippets handle cursor motion, but I'm not sure I can get the semicolon to go to the right spot. Ideas? Tricks?
Set your output to Insert as snippet. This will actually replace whatever the input is, but will interpret the output as a snippet. Then you do the processing of the line, and you snippet-escape the result, and add $0 at the location where you want the caret to end up. The library escape.rb will be of help to you, it contains an "e_sn" command that escapes the text for use in a snippet.
Best, Kevin
Haris
For new threads USE THIS: textmate@lists.macromates.com (threading gets destroyed and the universe will collapse if you don't) http://lists.macromates.com/mailman/listinfo/textmate
Whoops - that was a bit messed up. Here's the ACTUAL finished source (which escapes any '$'s other than the $0 it inserts.
#!/usr/bin/env ruby
$t = STDIN.read
if $t =~ /\A(.*);\Z/ $c = ENV['TM_LINE_INDEX'].to_i print $t.insert($c, ';$0').gsub(/$([^0])/, '$\1') else print $t.gsub('$', '$')+';$0' end
On 2/13/07, Kevin Cox kevintcox@gmail.com wrote:
Wow. Thanks so much!
If anybody's interested, here's the finished source:
#!/usr/bin/env ruby
$t = STDIN.read
if $t =~ /\A(.*);\Z/ $c = ENV['TM_LINE_INDEX'].to_i print $t.insert($c, ';$0') else print $t+';$0' end
On 2/13/07, Charilaos Skiadas skiadas@hanover.edu wrote:
On Feb 13, 2007, at 2:16 PM, Kevin Cox wrote:
Hello all,
input: selected text or line output: replace selected text activation: key equivalent ';' scope: "source"
#!/usr/bin/env ruby
$t = STDIN.read
if $t =~ /\A(.*);\Z/ $c = ENV['TM_LINE_INDEX'].to_i print $t.insert($c, ';') else print $t+';' end
Any idea how to move the cursor? Snippets handle cursor motion, but I'm not sure I can get the semicolon to go to the right spot. Ideas? Tricks?
Set your output to Insert as snippet. This will actually replace whatever the input is, but will interpret the output as a snippet. Then you do the processing of the line, and you snippet-escape the result, and add $0 at the location where you want the caret to end up. The library escape.rb will be of help to you, it contains an "e_sn" command that escapes the text for use in a snippet.
Best, Kevin
Haris
For new threads USE THIS: textmate@lists.macromates.com (threading gets destroyed and the universe will collapse if you don't) http://lists.macromates.com/mailman/listinfo/textmate
On 14. Feb 2007, at 20:19, Kevin Cox wrote:
Whoops - that was a bit messed up. Here's the ACTUAL finished source (which escapes any '$'s other than the $0 it inserts. [...]
We have the e_sn function in lib/escape.rb, this is preferable because it will do the right thing (i.e. also handle escaping of ` and ).
Here’s an alternative version using e_sn:
#!/usr/bin/env ruby require "#{ENV['TM_SUPPORT_PATH']}/lib/escape.rb"
line = STDIN.read
if line =~ /\A.*;\Z/ caret = ENV['TM_LINE_INDEX'].to_i print e_sn(line[0...caret]) + ';${0}' + e_sn(line[caret..-1]) else print e_sn(line) + ';' end
I use ${0} instead of $0 incase there is a number to the right of the caret (the manual isn’t really clear on whether or not $01 is equivalent to $1 or ${0}1 -- so let’s just avoid ever having that in a snippet ;) ).
Wow, thanks, Allan!
One minor modifcation to the regular expression:
#!/usr/bin/env ruby require "#{ENV['TM_SUPPORT_PATH']}/lib/escape.rb"
line = STDIN.read
if line =~ /\A.*(;|{)\Z/ caret = ENV['TM_LINE_INDEX'].to_i print e_sn(line[0...caret]) + ';${0}' + e_sn(line[caret..-1]) else print e_sn(line) + ';' end
This prevents it from putting a semicolon at the end of a line after an open {. Helps with for loops, for instance.
It's pretty clear I'm not a ruby programmer, eh?
On 2/14/07, Allan Odgaard throw-away-1@macromates.com wrote:
On 14. Feb 2007, at 20:19, Kevin Cox wrote:
Whoops - that was a bit messed up. Here's the ACTUAL finished source (which escapes any '$'s other than the $0 it inserts. [...]
We have the e_sn function in lib/escape.rb, this is preferable because it will do the right thing (i.e. also handle escaping of ` and ).
Here's an alternative version using e_sn:
#!/usr/bin/env ruby require "#{ENV['TM_SUPPORT_PATH']}/lib/escape.rb" line = STDIN.read if line =~ /\A.*;\Z/ caret = ENV['TM_LINE_INDEX'].to_i print e_sn(line[0...caret]) + ';${0}' + e_sn(line[caret..-1]) else print e_sn(line) + ';' end
I use ${0} instead of $0 incase there is a number to the right of the caret (the manual isn't really clear on whether or not $01 is equivalent to $1 or ${0}1 -- so let's just avoid ever having that in a snippet ;) ).
For new threads USE THIS: textmate@lists.macromates.com (threading gets destroyed and the universe will collapse if you don't) http://lists.macromates.com/mailman/listinfo/textmate
El 13/02/2007, a las 21:28, Charilaos Skiadas escribió:
Set your output to Insert as snippet. This will actually replace whatever the input is, but will interpret the output as a snippet. Then you do the processing of the line, and you snippet-escape the result, and add $0 at the location where you want the caret to end up. The library escape.rb will be of help to you, it contains an "e_sn" command that escapes the text for use in a snippet.
thanks.