As I set up Reformat Comment commands for the languages I use most frequently (LaTeX and R), it occurred to me that maybe there's a way to make a single call to rubywrap more generic, so that we don't need a command per bundle. This is the result:
#!/usr/bin/env ruby
$LOAD_PATH << "#{ENV["TM_SUPPORT_PATH"]}/lib" require "escape"
scope = ENV["TM_SCOPE"] case scope when /comment.(block|line).number-sign./ cstring = "# " when /comment.(block|line).percentage./ cstring = "% " end
flags = "" flags += " -p "#{cstring}" " flags += " --retabify" if ENV["TM_SOFT_TABS"] == "NO"
text =`echo -n "#{e_as(STDIN.read).gsub(/[$`]/, '\\\0')}" | ruby "# {ENV["TM_SUPPORT_PATH"]}/bin/rubywrap.rb" #{flags}` print e_sn(text)
The parameters are the same as the current command, with the exception of scope, which I set to "comment.line, comment.block".
I also added a gsub to the command because it was eating latex math and R symbols ($). There's probably a better solution to that. This seems to work for me, and should be extended easily by adding lines to the case statement for other languages. One advantage is that by specifying the comment character based on the scope, it ought to work for anything; it catches comments for both bash and perl, for instance, without any extra effort. I think it's kind of cool.
-Alan
On 23/8/2006, at 19:24, Alan Schussman wrote:
As I set up Reformat Comment commands for the languages I use most frequently (LaTeX and R), it occurred to me that maybe there's a way to make a single call to rubywrap more generic, so that we don't need a command per bundle. This is the result:
I was going to say that this belongs in the Source bundle.
scope = ENV["TM_SCOPE"] case scope when /comment.(block|line).number-sign./
Probably better to grab the comment character from the start of the input. Otherwise there is a more full mapping in the “Continue Line Comment” snippet in the Source bundle.
text =`echo -n "#{e_as(STDIN.read).gsub(/[$`]/, '\\\0')}" | ruby "#{ENV["TM_SUPPORT_PATH"]}/bin/rubywrap.rb" #{flags}`
This seems redundant and wrong. e_as is for escaping text to use in AppleScript strings.
The line can be:
text = `ruby "#{ENV["TM_SUPPORT_PATH"]}/bin/rubywrap.rb" #{flags}`
I also added a gsub to the command because it was eating latex math and R symbols ($). There's probably a better solution to that.
Likely because of the Insert as Snippet -- but the e_sn should take care of that.
I am however not sure inserting as snippet is ideal -- I reckon this was to preserve the indent, but maybe better to Replace Text and have the command indent properly.
Thanks for the feedback, Allan.
On Aug 23, 2006, at 10:41 AM, Allan Odgaard wrote:
Probably better to grab the comment character from the start of the input. Otherwise there is a more full mapping in the “Continue Line Comment” snippet in the Source bundle.
Grabbing the start of the input works well, and it means setting the comment parameter based on what actually sits at the beginning of the comment scope, so that it will catch "%comment" or "% comment" or "%% comment". Nice.
The line can be:
text = `ruby "#{ENV["TM_SUPPORT_PATH"]}/bin/rubywrap.rb" #{flags}`
Here's where I go "huh." That works, but 1) I don't at all get how the input is passed to the command; and 2) if I call on STDIN.read prior to this line (by using it to get the beginning of the input), then that line fails to get any input, and I have to manually pipe the text back into it. What's happening there?
I also added a gsub to the command because it was eating latex math and R symbols ($). There's probably a better solution to that.
Likely because of the Insert as Snippet -- but the e_sn should take care of that.
I am however not sure inserting as snippet is ideal -- I reckon this was to preserve the indent, but maybe better to Replace Text and have the command indent properly.
Excellent -- thanks for pointing out what e_as was doing. When inserting as a snippet, e_sn does the job, and replacing the text instead of inserting as snippet also works, though you're right that it doesn't re-indent before the comment.
Here's what I have now: --- #!/usr/bin/env ruby
$LOAD_PATH << "#{ENV["TM_SUPPORT_PATH"]}/lib" require "escape"
ctext = STDIN.read cs = ctext.split(/\s/,1) cs[0] =~ /(^[%#/-]+\s*)/ cstring = $1
flags = "" flags += " -p "#{cstring}" " flags += " --retabify" if ENV["TM_SOFT_TABS"] == "NO"
text =`echo -n "#{e_sn(ctext)}" | ruby "#{ENV["TM_SUPPORT_PATH"]}/bin/ rubywrap.rb" #{flags}`
print text ---
-Alan
On Aug 23, 2006, at 4:33 PM, Alan Schussman wrote:
Probably better to grab the comment character from the start of the input. Otherwise there is a more full mapping in the “Continue Line Comment” snippet in the Source bundle.
Grabbing the start of the input works well, and it means setting the comment parameter based on what actually sits at the beginning of the comment scope, so that it will catch "%comment" or "% comment" or "%% comment". Nice.
Yeah, this seems clever. I think we need to make your regex for this a little more lenient though...
The line can be:
text = `ruby "#{ENV["TM_SUPPORT_PATH"]}/bin/rubywrap.rb" #
{flags}`
Here's where I go "huh." That works, but 1) I don't at all get how the input is passed to the command; and 2) if I call on STDIN.read prior to this line (by using it to get the beginning of the input), then that line fails to get any input, and I have to manually pipe the text back into it. What's happening there?
Well, if you call read(), you consume the input, so it's not there to pass on to the child process.
I also added a gsub to the command because it was eating latex math and R symbols ($). There's probably a better solution to that.
Likely because of the Insert as Snippet -- but the e_sn should take care of that.
I am however not sure inserting as snippet is ideal -- I reckon this was to preserve the indent, but maybe better to Replace Text and have the command indent properly.
Excellent -- thanks for pointing out what e_as was doing. When inserting as a snippet, e_sn does the job, and replacing the text instead of inserting as snippet also works, though you're right that it doesn't re-indent before the comment.
Hmm, I think you are still having trouble understanding where to use these:
e_sh(): for data headed to the shell e_sn(): for data about to be shown as a TextMate snippet
Here's the code I just moved into the Source bundle. Let me know if this is working please:
#!/usr/bin/env ruby
$LOAD_PATH << "#{ENV["TM_SUPPORT_PATH"]}/lib" require "escape" require "exit_codes"
ctext = STDIN.read if ctext =~ /^\s*([^\s\w]+\s*)/ cstring = $1 else TextMate.exit_show_tool_tip("Unable to determine comment character.") end
flags = %Q{ -p "#{cstring}"} flags += " --retabify" if ENV["TM_SOFT_TABS"] == "NO"
command = "ruby #{e_sh(ENV["TM_SUPPORT_PATH"])}/bin/rubywrap.rb # {flags}" text = open("| #{command}", "r+") do |wrapper| wrapper << ctext wrapper.close_write wrapper.read end
print e_sn(text)
__END__
James Edward Gray II
On Aug 23, 2006, at 3:20 PM, James Edward Gray II wrote:
text = `ruby "#{ENV["TM_SUPPORT_PATH"]}/bin/rubywrap.rb" #
{flags}`
Here's where I go "huh." That works, but 1) I don't at all get how the input is passed to the command; and 2) if I call on STDIN.read prior to this line (by using it to get the beginning of the input), then that line fails to get any input, and I have to manually pipe the text back into it. What's happening there?
Well, if you call read(), you consume the input, so it's not there to pass on to the child process.
I was guessing that was the case. But how about the first question, if there is input how does that statement suck it up automatically? (Apologies if this is excruciatingly basic; I'm just trying to understand how the input gets passed without explicitly doing so.)
Hmm, I think you are still having trouble understanding where to use these:
e_sh(): for data headed to the shell
Aha, now that I know there's e_sh(), I do understand it. Thanks :)
Here's the code I just moved into the Source bundle. Let me know if this is working please:
It looks like it works well for most cases, but I think the more lenient regex causes a problem in the case of a latex comment such as "%\usepackage" (note no space); in that case, the comment parameter is set to "%" and the backslash ends up causing problems.
Cheers- -Alan
On Aug 23, 2006, at 5:51 PM, Alan Schussman wrote:
On Aug 23, 2006, at 3:20 PM, James Edward Gray II wrote:
text = `ruby "#{ENV["TM_SUPPORT_PATH"]}/bin/rubywrap.rb" #
{flags}`
Here's where I go "huh." That works, but 1) I don't at all get how the input is passed to the command; and 2) if I call on STDIN.read prior to this line (by using it to get the beginning of the input), then that line fails to get any input, and I have to manually pipe the text back into it. What's happening there?
Well, if you call read(), you consume the input, so it's not there to pass on to the child process.
I was guessing that was the case. But how about the first question, if there is input how does that statement suck it up automatically? (Apologies if this is excruciatingly basic; I'm just trying to understand how the input gets passed without explicitly doing so.)
To put it simply, this is just how Unix works. ;)
Child process inherit STDOUT, STDIN, and STDERR from their parent process.
Here's the code I just moved into the Source bundle. Let me know if this is working please:
It looks like it works well for most cases, but I think the more lenient regex causes a problem in the case of a latex comment such as "%\usepackage" (note no space); in that case, the comment parameter is set to "%" and the backslash ends up causing problems.
If I remove backslash from the characters would that cover us? I don't *think* it's a comment in any language I know...
James Edward Gray II
On Aug 23, 2006, at 4:25 PM, James Edward Gray II wrote:
To put it simply, this is just how Unix works. ;)
Child process inherit STDOUT, STDIN, and STDERR from their parent process.
Gotcha. So if stdin exists, it's used. Neat. (Thanks, Allan, too.)
Here's the code I just moved into the Source bundle. Let me know if this is working please:
It looks like it works well for most cases, but I think the more lenient regex causes a problem in the case of a latex comment such as "%\usepackage" (note no space); in that case, the comment parameter is set to "%" and the backslash ends up causing problems.
If I remove backslash from the characters would that cover us? I don't *think* it's a comment in any language I know...
I would think that would work. At least until the BackSlashAsComment bundle comes along, in which case we can revisit it.
The only other change I'd make would be to add comment.block to the context. I don't know how many languages do it, but I saw that at least perl set context to comment.block instead of comment.line.
-Alan
On 24/8/2006, at 1:34, Alan Schussman wrote:
The only other change I'd make would be to add comment.block to the context. I don't know how many languages do it, but I saw that at least perl set context to comment.block instead of comment.line.
If so, Perl should be fixed. Block comments should use another mechanism to have their text reformatted (I show one approach in the customization screencast ;) .)
On Aug 23, 2006, at 19:06, Allan Odgaard wrote:
On 24/8/2006, at 1:34, Alan Schussman wrote:
The only other change I'd make would be to add comment.block to the context. I don't know how many languages do it, but I saw that at least perl set context to comment.block instead of comment.line.
If so, Perl should be fixed. Block comments should use another mechanism to have their text reformatted (I show one approach in the customization screencast ;) .)
Perl does not have block comments. But I defined comments that start in the first column as block comments. That allows me to do different highlighting for what I consider top level comments. This was quite deliberate!
Gerd
On 24/8/2006, at 6:32, Gerd Knops wrote:
If so, Perl should be fixed. Block comments should use another mechanism to have their text reformatted (I show one approach in the customization screencast ;) .)
Perl does not have block comments. But I defined comments that start in the first column as block comments. That allows me to do different highlighting for what I consider top level comments. This was quite deliberate!
I had a suspicion this was the case. The proper scope would then be something like:
comment.line.number-sign.full-line.perl
Or whatever you deem appropriate to call such construct.
On Aug 23, 2006, at 11:32 PM, Gerd Knops wrote:
On Aug 23, 2006, at 19:06, Allan Odgaard wrote:
On 24/8/2006, at 1:34, Alan Schussman wrote:
The only other change I'd make would be to add comment.block to the context. I don't know how many languages do it, but I saw that at least perl set context to comment.block instead of comment.line.
If so, Perl should be fixed. Block comments should use another mechanism to have their text reformatted (I show one approach in the customization screencast ;) .)
Perl does not have block comments.
Sure does.
They are intended for the POD documentation processor, but even the Perl documentation shows how to use them as block comments:
http://faq.perl.org/perlfaq7.html#How_can_I_comment_ou
James Edward Gray II
On Aug 23, 2006, at 6:34 PM, Alan Schussman wrote:
On Aug 23, 2006, at 4:25 PM, James Edward Gray II wrote:
If I remove backslash from the characters would that cover us? I don't *think* it's a comment in any language I know...
I would think that would work. At least until the BackSlashAsComment bundle comes along, in which case we can revisit it.
OK, try the new version. Should be fixed up, I hope.
The only other change I'd make would be to add comment.block to the context. I don't know how many languages do it, but I saw that at least perl set context to comment.block instead of comment.line.
I've repaired the Perl grammar.
This command is for line comments. Perl's block comments do not begin with a #.
James Edward Gray II
On 24/8/2006, at 0:51, Alan Schussman wrote:
[...] But how about the first question, if there is input how does that statement suck it up automatically?
When you spawn a new process that process with automatically inherit stdin/out/err of the current process (unless measures are taken to supply it with new pipes for any of these.)
Btw (James): Please test for TM_SOFT_TABS being YES instead of NO -- in a future version I will not expose this variable when soft tabs are not enabled.
Hi, I'm not sure if anyone's brought this up before, but I think there are three problems with the Reformat Comment command in the Source bundle:
1. It doesn't respect the wrap column (the TM_COLUMNS variable) 2. It adds an extra newline at the end of the comment 3. It doesn't correctly handle comments that are indented
Are these actually problems, or am I thinking about the purpose the command incorrectly? If they are actually problems, I think the way to fix them is by changing two of the lines in the command, and switching the Input to Selected Text or Line (rather than Selected Text or Scope) since this will pass leading whitespace to the rubywrap script. The updated command is included below.
Is this right? I came across this problem while fiddling with a Python script; I'm not a very experienced programmer and I really have no idea if these changes cause problems with other languages. Thanks for any feedback!
-Daniel
#!/usr/bin/env ruby
$LOAD_PATH << "#{ENV["TM_SUPPORT_PATH"]}/lib" require "escape" require "exit_codes"
ctext = STDIN.read if ctext =~ /^\s*(.[^\s\w\]*\s*)/ cstring = $1 else TextMate.exit_show_tool_tip("Unable to determine comment character.") end
flags = %Q{-p "#{cstring}"} flags += " --retabify" unless ENV["TM_SOFT_TABS"] == "YES" flags += " -c #{ENV["TM_COLUMNS"]}"
command = "ruby #{e_sh(ENV["TM_BUNDLE_SUPPORT"])}/bin/rubywrap.rb #{flags}" text = open("| #{command}", "r+") do |wrapper| wrapper << ctext wrapper.close_write wrapper.read end
print e_sn(text.chomp)
On 18 May 2008, at 02:57, Daniel Grady wrote:
Hi, I'm not sure if anyone's brought this up before, but I think there are three problems with the Reformat Comment command in the Source bundle:
- It doesn't respect the wrap column (the TM_COLUMNS variable)
- It adds an extra newline at the end of the comment
- It doesn't correctly handle comments that are indented
[...] switching the Input to Selected Text or Line (rather than Selected Text or Scope) since this will pass leading whitespace to the rubywrap script.
I don’t see how that will fix #3, at least not if we want it to work on multiple (commented) lines without having to manually select them first (but that already works).
The long-term plan is to introduce a leading whitespace scope for single-line comments, and then let this command select comments including this whitespace scope.
Allan Odgaard <throw-away-2@...> writes:
I don’t see how that will fix #3, ...
Good point. I was just using the command to wrap single line comments, and this didn't occur to me. The other two points still seem valid, if trivial.
The long-term plan is to introduce a leading whitespace scope for single-line comments, and then let this command select comments including this whitespace scope.
That will be nice.