Customize matching pairs - add to or remove from the package defaults #249
Conversation
Instead of adding an "exclude pairs", I would rename "Add Pairs" to "Autocompleted Characters" (or similar), then make the default of that setting include the current list of default pairs. That would satisfy both requirements. In addition, the "Autocomplete Brackets/Smart Quotes" options can be removed since "Autocompleted Characters" would handle that as well. There should also be some more documentation regarding /cc @atom/feedback |
Also, with the current setup it's impossible to add |
expect(buffer.lineForRow(0)).toBe "<>" | ||
expect(editor.getCursorBufferPosition()).toEqual([0, 1]) | ||
|
||
# Scope tests inexplicably fail |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests will need to be fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started down a scary road on this one - ended up time-boxing and disabling the tests at this point. The problem seems to be with the Spec library itself in the mocking of the testing editor. I added a bunch of console.log lines all over the code - all of them confirmed that I was grabbing from the correct scope. For some reason, the way the test codebase is implementing the atom.config.set at scope level, it isn't triggering a callback.
I gave myself a TODO to create some tests of the tests (heh) to try to consistently recreate what I see as a potential bug. Then I can go about fixing.
@@ -29,6 +29,25 @@ class BracketMatcher | |||
else | |||
@pairedCharacters = @defaultPairs | |||
|
|||
excludePairs: (excludePairs) -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disclaimer: I am unfamiliar with the structure of bracket-matcher.
It looks like this logic is being duplicated in bracket-matcher-view...would it be possible to unify the two?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I noticed that as well. It is now even more similar after the refactoring I did for performance. bracket-matcher.coffee was previously parsing and modifying the config options every time an edit operation was being performed. Ouch! I've changed it so that an update to config routine is called by the constructor; I then added callbacks to each of the config options so that the update config routine is called anytime the options change.
I ended up going back to bracket-matcher-view.coffee and putting in very similar behaviors. So yes, it should be refactored to have shared code, and only separate concerns where necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've refactored the package quite a bit now in an effort to remove duplicated code. This was / is harder than I thought, as it isn't always code that is duplicated, but behavior. I found logic written two different ways between those two files. I believe my rewrite cleans it up a decent amount, and provides for a better separation of concerns.
@@ -544,6 +544,44 @@ describe "bracket matching", -> | |||
expect(buffer.lineForRow(0)).toBe "{}" | |||
expect(editor.getCursorBufferPosition()).toEqual([0, 1]) | |||
|
|||
describe "when addPairs configuration is set globally", -> | |||
it "inserts a matching carat", -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
carat -> caret
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doh! Good catch.
This should also fix #121. |
@50Wliu - Good point. This occurred to me when I was refactoring some of the codebase - I ended up submitting so I could get some feedback before proceeding. It seems that the design pattern for Atom follows what you suggest, having a default behavior, which is shown in light gray within text boxes, which then becomes an all-or-nothing setting. I'll make that change, it would definitely make more sense. |
Also fixes #171. |
Agreed. I used the |
Ok, I've changed it to not even have a separator; looks a lot cleaner, and removes the need to worry about escaping for any reason. So a line in the config would look like this: Cool? |
Yep! Except, of course, for |
Ironically, comma's now work, but only if added via the config.cson file. ;) |
62d00df
to
079141d
Compare
@@ -149,7 +91,7 @@ class BracketMatcher | |||
previousCharacter = previousCharacters.slice(-1) | |||
|
|||
hasEscapeSequenceBeforeCursor = previousCharacters.match(/\\/g)?.length >= 1 # To guard against the "\\" sequence | |||
if (@pairedCharacters[previousCharacter] is nextCharacter) and not hasEscapeSequenceBeforeCursor and @getScopedSetting('bracket-matcher.autocompleteBrackets') | |||
if (@matchManager.pairedCharacters[previousCharacter] is nextCharacter) and not hasEscapeSequenceBeforeCursor and @getScopedSetting('bracket-matcher.autocompleteBrackets') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't you also use autocompletePairs for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
autocompletePairs is a local variable only in scope in the processAutoPairs method in MatchManager (line 17 - 21).
|
||
module.exports = | ||
class MatchManager | ||
smartQuotePairs: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this setting is currently enabled by default, would it make sense to 🔥 all of these and add them to the new autocompletePairs default as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, that's easy enough to chop out. I wasn't sure if there was a specific purpose or desire to treat smartquotes distinctly. I personally never use them...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Just realized I forgot to hit the "comment" button after submitting my review comments... 🙈 |
My two cents on the issue. Being able to explicitly remove some characters from auto-matching while implicitly leaving the other defaults in is something I'd prefer to see. I.e. I'd like to have both 'Autocomplete Characters' and 'Excluded Characters'. My reasoning being that if I want to disable some characters (e.g. For example, I would prefer something like this: ".some.scope":
"bracket-matcher":
excludeCharacters: ["'"] to ".some.scope":
"bracket-matcher":
autocompleteCharacters: ['()', '[]', '""', '{}' , "``"] Also second option implies that I will update my config by hand in case defaults change, although that's arguably is not that big of an issue. |
Yes, that's something that I was considering bringing up with the /cc @atom/feedback |
@maxbrunsfeld @nathansobo @iolsen I was wondering if you guys had any feedback on the I definitely feel this PR is a improvement over the current behavior, but I feel the wording for Also, was wondering about the comment @50Wliu made :
|
After staring at this long enough to understand what's going on, I agree. I do think it makes sense to allow this to be customized beyond the source of a specific language bundle, but that name is misleading... It's really about placing the closing character of the pair on a new line. Maybe |
Hey @nathansobo @potto007 @50Wliu @Ben3eeE Instead of Pairs to Format Automatically format the pair by adding a newline when user clicks enter between the pair defined. Might be good to add a example to the README as well: I think it would be good to have this functionality in this package, but the indention behavior is specific to the language. |
I don't know. I still think this should be handled by the individual languages. If not, Pairs to Format still sounds ambiguous. Maybe Naming things is hard 😖. |
@50Wliu Can you articulate your position a bit... What if a user wants to have this behavior and a given package doesn't support it? Should the only route be submit a PR on the package? @50Wliu @ungb I guess I also like |
Never mind. As I was writing out my explanation I've decided that since it's going to be a scoped setting regardless, it'll be fine and language packages will be available to override it/add their own pairs, which was my main concern. Which brings me to another point... For example, |
@50Wliu Great points. Do you have any ideas for how we could improve our APIs to fix this issue? Maybe opening up an issue to get a discussion started would be helpful if you have the inclination. |
I also think |
@ungb Thanks for making those changes. I'm good with them. I'm excited to watch this get merged! |
Actually - one more thing - I'm updating the README.md to reflect the name change. |
Ah I missed that, Thanks @potto007, Will merge today once build passes. |
As I'm watching Travis take its typical 15 - 30 minutes to allocate an OS X environment, I thought I'd ask: do any of you know if there's a good reason for the I see it in this early Atom documentation: http://blog.atom.io/2014/04/25/ci-for-your-packages.html |
@50Wliu @Ben3eeE @ungb Replace
Proof in the pudding: https://travis-ci.org/potto007/bracket-matcher |
@potto007 would love a PR to change the build environment :). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly just documentation suggestions.
|
||
You can customize matching pairs in Bracket Matcher at any time. You can do so either Globally via the Settings view (<kbd>cmd-,</kbd>) or at the Scope level via `config.cson` (<kbd>cmd-shift-p</kbd> + "config"). Changes take effect immediately. | ||
|
||
* <b>Autocomplete Characters</b> - Comma-separated pairs that the editor will treat as brackets / quotes. Entries in this field override the package defaults. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are no package defaults anymore, right?
Also, use **
notation for bold.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, yes: https://github.com/potto007/bracket-matcher/blob/custom-pairs/package.json#L19-L22
Oops on the bolds. I'll fix that.
* <b>Autocomplete Characters</b> - Comma-separated pairs that the editor will treat as brackets / quotes. Entries in this field override the package defaults. | ||
* ie: `<>, (), []` | ||
|
||
* <b>Pairs With Extra Newline</b> - Comma-separated pairs that enhance the editor's Auto Indent feature. When used, a newline is automatically added between the pair when enter is pressed between them. Note: This feature is meant to be used in combination with brackets defined for indentation by the active language mode (increaseIndentPattern / decreaseIndentPattern). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
increaseIndentPattern and decreaseIndentPattern should be in backticks.
``` | ||
|
||
###### config.cson | ||
In addition to Global configs, you are able to add scope-specific modifications to Atom in `config.cson`. This is especially useful for editor rule changes specific to each language. Scope specific configs override package defaults <i>and</i> global configs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about: In addition to the global settings, you are also able...
. Same thing at the end: global configs -> global settings. Also, hyphenate Scope-specific and change configs to settings.
*
or _
notation for italics.
Again, there really aren't any defaults anymore. Everything's configurable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll implement those changes. WRT defaults, I'm referring to the package.json defaults.
###### config.cson | ||
In addition to Global configs, you are able to add scope-specific modifications to Atom in `config.cson`. This is especially useful for editor rule changes specific to each language. Scope specific configs override package defaults <i>and</i> global configs. | ||
Example: | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add cson to the backticks so that it gets syntax-highlighted
Example: | ||
``` | ||
".rust.source": | ||
"bracket-matcher": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing indentation
@updateConfig() | ||
|
||
# Subscribe to config changes | ||
@subscriptions.add atom.config.observe 'bracket-matcher.autocompleteBrackets', {scope: @editor.getRootScopeDescriptor()}, (newConfig) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There doesn't seem to be a reason to update the config when bracket autocompletion is turned on or off, is there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True - I think I left this in after a troubleshooting session.
# Subscribe to config changes | ||
@subscriptions.add atom.config.observe 'bracket-matcher.autocompleteBrackets', {scope: @editor.getRootScopeDescriptor()}, (newConfig) => | ||
@updateConfig() | ||
@subscriptions.add atom.config.observe 'bracket-matcher.wrapSelectionsInBrackets', {scope: @editor.getRootScopeDescriptor()}, (newConfig) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same with this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True - I think I left this in after a troubleshooting session.
"items": { | ||
"type": "string" | ||
} | ||
}, | ||
"autocompleteBrackets": { | ||
"type": "boolean", | ||
"default": true, | ||
"description": "Autocomplete bracket and quote characters, such as `(` and `)`, and `\"`." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Autocomplete the characters defined in the
autocompleteBrackets
setting
This setting name is a bit misleading now, but we can't change it without breaking existing configs. Oh well.
"type": "boolean", | ||
"default": true, | ||
"description": "Autocomplete smart quote characters, such as `“` and `”`, and `«` and `»`." | ||
}, | ||
"wrapSelectionsInBrackets": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description for this one can also be updated.
@@ -27,10 +27,10 @@ Settings view (<kbd>cmd-,</kbd>). | |||
|
|||
You can customize matching pairs in Bracket Matcher at any time. You can do so either Globally via the Settings view (<kbd>cmd-,</kbd>) or at the Scope level via `config.cson` (<kbd>cmd-shift-p</kbd> + "config"). Changes take effect immediately. | |||
|
|||
* <b>Autocomplete Characters</b> - Comma-separated pairs that the editor will treat as brackets / quotes. Entries in this field override the package defaults. | |||
* **Autocomplete Characters** - Comma-separated pairs that the editor will treat as brackets / quotes. Entries in this field override the package defaults. | |||
* ie: `<>, (), []` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to avoid latin abbreviations: use "for example" instead.
(See https://github.com/atom/flight-manual.atom.io/blob/master/CONTRIBUTING.md#language)
@@ -27,10 +27,10 @@ Settings view (<kbd>cmd-,</kbd>). | |||
|
|||
You can customize matching pairs in Bracket Matcher at any time. You can do so either Globally via the Settings view (<kbd>cmd-,</kbd>) or at the Scope level via `config.cson` (<kbd>cmd-shift-p</kbd> + "config"). Changes take effect immediately. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Globally and Scope shouldn't be capitalized. Settings View should be though.
Also,
...or at the scope level via your
config.cson
.
You don't need to include the shortcuts. I think it's safe to assume that if they're reading this they should know how to get to the Settings View and config.cson.
* ie: `<>, (), []` | ||
|
||
* <b>Pairs With Extra Newline</b> - Comma-separated pairs that enhance the editor's Auto Indent feature. When used, a newline is automatically added between the pair when enter is pressed between them. Note: This feature is meant to be used in combination with brackets defined for indentation by the active language mode (increaseIndentPattern / decreaseIndentPattern). | ||
* **Pairs With Extra Newline** - Comma-separated pairs that enhance the editor's Auto Indent feature. When used, a newline is automatically added between the pair when enter is pressed between them. Note: This feature is meant to be used in combination with brackets defined for indentation by the active language mode (`increaseIndentPattern` / `decreaseIndentPattern`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uncapitalize auto indent.
This allows you to add or remove matching pairs from Bracket Matcher at any time. You can do so either Globally via the Settings view (cmd-,) or at the Scope level via
config.cson
(cmd-shift-p + "config"). Changes take effect immediately.I got tired of fighting this while developing in Rust. Upon searching about it, I found numerous discussions about the need, and pinpointed two existing issues pertaining to this enhancement. Issue #214 requests the ability to choose which matching pairs to use. Issue #236 requests the ability to turn off the matching functionality for certain characters.