I'm trying to do something a little weird and I'd like some help. It has to do with tabs.
The local coding standard is to indent with hard tabs, 8 characters wide. So far so good. But we want to avoid tabs within the line, after the first non-whitespace character. Example:
int foo = 1234; // foo int bar = 5678; // bar int foobar = 12345678; // foobar
So before the "int" there should be a hard tab, but before the "=" and "//" characters there should just be spaces. I'd like to use the tab key for all of this (ie., <tab> i n t <space> f o o <tab> = 1 2 3 4 ...), changing its behavior from hard tabs to soft tabs depending on where I am within the line.
I wrote a command script that will actually do this and bound it to the tab key with Activation: Key Equivalent. But, unfortunately stealing the tab key like this breaks ordinary tab triggers and tabbing between snippet fields.
Anyone have suggestions on how overload the tab key without losing what it already does? I'd also accept some way of binding tab triggers and snippets to some other keystroke.
On Apr 5, 2007, at 9:49 AM, Steve King wrote:
Anyone have suggestions on how overload the tab key without losing what it already does? I'd also accept some way of binding tab triggers and snippets to some other keystroke.
I'm thinking you should set TextMate to use "Soft Tabs" with 8 spaces and then use some Snippet or Command trickery to make it insert an actual Tab when you hit the ⇥ key from the beginning of a line.
There doesn't seem to be a way to set "beginning of a line" as a Tab Trigger, but perhaps you could modify the relevant language grammars to have a "beginning of line" scope or an "empty line" scope and have a Snippet or Command with a Key Equivalent of ⇥ that inserts a literal Tab only in that scope.
I say "Snippet or Command" because I'm not sure which is best here. When Snippets containing actual Tabs are used, the Tabs are usually replaced according to your preferences. There may be a way to escape the Tab, or some hidden XML property that can be manually added to the Snippet to prevent this behavior. Otherwise, you might need a Command.
--- Rob McBroom http://www.skurfer.com/ I didn't "switch" to Apple... my OS did.
On Apr 5, 2007, at 12:35 PM, Rob McBroom wrote:
On Apr 5, 2007, at 9:49 AM, Steve King wrote:
Anyone have suggestions on how overload the tab key without losing what it already does? I'd also accept some way of binding tab triggers and snippets to some other keystroke.
I'm thinking you should set TextMate to use "Soft Tabs" with 8 spaces and then use some Snippet or Command trickery to make it insert an actual Tab when you hit the ⇥ key from the beginning of a line.
There doesn't seem to be a way to set "beginning of a line" as a Tab Trigger, but perhaps you could modify the relevant language grammars to have a "beginning of line" scope or an "empty line" scope and have a Snippet or Command with a Key Equivalent of ⇥ that inserts a literal Tab only in that scope.
I say "Snippet or Command" because I'm not sure which is best here. When Snippets containing actual Tabs are used, the Tabs are usually replaced according to your preferences. There may be a way to escape the Tab, or some hidden XML property that can be manually added to the Snippet to prevent this behavior. Otherwise, you might need a Command.
Rob McBroom http://www.skurfer.com/ I didn't "switch" to Apple... my OS did.
Or you could just make a simple snippet that insets a real tab character and set it to use option-tab Then you just have to always remember to hit option-tab for a real tab
thomas Aylott — subtleGradient — CrazyEgg — sixteenColors
On 4/5/07, Thomas Aylott (subtleGradient) oblivious@subtlegradient.com wrote:
On Apr 5, 2007, at 12:35 PM, Rob McBroom wrote:
On Apr 5, 2007, at 9:49 AM, Steve King wrote:
Anyone have suggestions on how overload the tab key without losing what it already does? I'd also accept some way of binding tab triggers and snippets to some other keystroke.
I'm thinking you should set TextMate to use "Soft Tabs" with 8 spaces and then use some Snippet or Command trickery to make it insert an actual Tab when you hit the ⇥ key from the beginning of a line.
There doesn't seem to be a way to set "beginning of a line" as a Tab Trigger, but perhaps you could modify the relevant language grammars to have a "beginning of line" scope or an "empty line" scope and have a Snippet or Command with a Key Equivalent of ⇥ that inserts a literal Tab only in that scope.
I say "Snippet or Command" because I'm not sure which is best here. When Snippets containing actual Tabs are used, the Tabs are usually replaced according to your preferences. There may be a way to escape the Tab, or some hidden XML property that can be manually added to the Snippet to prevent this behavior. Otherwise, you might need a Command.
Rob McBroom
I didn't "switch" to Apple... my OS did.
Or you could just make a simple snippet that insets a real tab character and set it to use option-tab Then you just have to always remember to hit option-tab for a real tab
Or you could just overload cmd-s and write a script that converts your initial soft-tabs when you save. Very easy to do.
Ed
On Thu, 5 Apr 2007, Rob McBroom wrote:
There doesn't seem to be a way to set "beginning of a line" as a Tab Trigger, but perhaps you could modify the relevant language grammars to have a "beginning of line" scope or an "empty line" scope and have a Snippet or Command with a Key Equivalent of ⇥ that inserts a literal Tab only in that scope.
This *almost* works, but my language-grammar-fu is not strong enough. In the C grammar, for example, I haven't been able to come up with a scoping rule to select '^\s*' that doesn't interfere with existing rules which contain whitespace anchored at the start of the line (like pre-processor directives). I think I'd have to edit every existing rule which contains '^\s*' to capture that leading whitespace into its own scope. That's way more grief than I'm looking for.
And, as I reflect on it some more, just re-assigning the tab key isn't exactly what I want. I also want cmd-] to insert hard tabs to indent a block, which wouldn't happen with this technique. Though I suppose I could write another command for cmd-] that would do that.
On Apr 5, 2007, at 5:15 PM, Steve King wrote:
On Thu, 5 Apr 2007, Rob McBroom wrote:
There doesn't seem to be a way to set "beginning of a line" as a Tab Trigger, but perhaps you could modify the relevant language grammars to have a "beginning of line" scope or an "empty line" scope and have a Snippet or Command with a Key Equivalent of ⇥ that inserts a literal Tab only in that scope.
This *almost* works, but my language-grammar-fu is not strong enough. In the C grammar, for example, I haven't been able to come up with a scoping rule to select '^\s*' that doesn't interfere with existing rules which contain whitespace anchored at the start of the line (like pre-processor directives). I think I'd have to edit every existing rule which contains '^\s*' to capture that leading whitespace into its own scope. That's way more grief than I'm looking for.
And, as I reflect on it some more, just re-assigning the tab key isn't exactly what I want. I also want cmd-] to insert hard tabs to indent a block, which wouldn't happen with this technique. Though I suppose I could write another command for cmd-] that would do that.
I actually think what you want is to leave the tab key alone, and the same for the other keys, and to just write a trivial 3 line script to do the kind of change you need to the entire document whenever it's run. (I think someone already suggested something similar). Then, assuming you use some sort of svn type system, you should be able to have a pre/post-commit hook or whatnot that runs this script.
-- Steve King, steve@narbat.com
Haris Skiadas Department of Mathematics and Computer Science Hanover College
On Thu, 5 Apr 2007, Charilaos Skiadas wrote:
I actually think what you want is to leave the tab key alone, and the same for the other keys, and to just write a trivial 3 line script to do the kind of change you need to the entire document whenever it's run. (I think someone already suggested something similar). Then, assuming you use some sort of svn type system, you should be able to have a pre/post-commit hook or whatnot that runs this script.
That's actually not such a good idea, at least not around here. I'm not the only one who works on this code, and it's considered somewhat anti-social to make formatting changes to parts of a module you're not actually changing. Even just changing whitespace messes with others when they do a 'diff' to see what changes were made. In an ideal world, the rest of the code would already be formatted appropriately so such a script wouldn't actually change anything other than lines I worked on. In an ideal world. :-)
I can write such a script and assign a key to apply it to just a selection or block, though. I think that's what'll work best for me.
BTW, in 2.0 I really, *really* hope the API will expose a way for scripts to execute arbitrary editor commands. It makes weird scripting requests like this a lot easier.
On Apr 6, 2007, at 9:31 AM, Steve King wrote:
On Thu, 5 Apr 2007, Charilaos Skiadas wrote:
I actually think what you want is to leave the tab key alone, and the same for the other keys, and to just write a trivial 3 line script to do the kind of change you need to the entire document whenever it's run. (I think someone already suggested something similar). Then, assuming you use some sort of svn type system, you should be able to have a pre/post-commit hook or whatnot that runs this script.
That's actually not such a good idea, at least not around here. I'm not the only one who works on this code, and it's considered somewhat anti-social to make formatting changes to parts of a module you're not actually changing. Even just changing whitespace messes with others when they do a 'diff' to see what changes were made. In an ideal world, the rest of the code would already be formatted appropriately so such a script wouldn't actually change anything other than lines I worked on. In an ideal world. :-)
I suppose you can then write a more interesting script, that first runs an svn diff on the file, and then finds the changed lines from there and only re-indents those, leaving the rest of the file untouched.
But my suggestion about the pre/post commit hook was really that this should be happening for anyone committing to the codebase, not just to your commits. If you have particular formatting requirements, then it seems to me that the right way about it is to not allow anything not following these instructions to be committed in the first place.
I can write such a script and assign a key to apply it to just a selection or block, though. I think that's what'll work best for me.
BTW, in 2.0 I really, *really* hope the API will expose a way for scripts to execute arbitrary editor commands. It makes weird scripting requests like this a lot easier.
-- Steve King, steve@narbat.com
Haris Skiadas Department of Mathematics and Computer Science Hanover College