-
Notifications
You must be signed in to change notification settings - Fork 404
Decorate merge conflicts within TextEditors #385
Conversation
cb662e6
to
2761dd3
Compare
lib/views/decoration.js
Outdated
|
||
import Portal from './portal'; | ||
|
||
export default class Decoration extends React.Component { |
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.
@BinaryMuse: here's my Decoration
component, largely cargo-culted from Panel
and PaneItem
. I'm also not actually using it for any decorations that use a subtree yet (although that will change before this PR is ready). I'd ❤️ any early feedback you'd have 😄
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.
This looks awesome!
render() { | ||
const controllers = this.state.conflictingEditors.map(editor => ( | ||
<EditorConflictController | ||
key={editor.getPath()} |
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.
Is it possible we'll have multiple editors open with the same path (such as when splitting)?
@@ -16,7 +16,7 @@ import ReactDom from 'react-dom'; | |||
* rendered into it. Note that this uses `unstable_renderSubtreeIntoContainer` | |||
* to preserve context in the subtree. | |||
* | |||
* `getElement()` allows acccess to the React subtree container element. | |||
* `getElement()` allows access to the React subtree container element. |
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.
😅
bb8bfd0
to
757c2a3
Compare
2804678
to
61b297e
Compare
The extra layer will make it easier to write the conflict resolution callbacks.
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.
Feedback from a ScreenHero code review extravaganza with @kuychaco and @BinaryMuse ✨
lib/models/conflicts/conflict.js
Outdated
} | ||
|
||
export default class Conflict { | ||
|
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.
🔥
lib/models/conflicts/conflict.js
Outdated
conflict() { | ||
return new Conflict(this.ours, this.separator, this.base, this.theirs); | ||
} | ||
|
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.
🔥
); | ||
} | ||
|
||
getConflictingEditors() { |
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.
@kuychaco: If you don't want to mess around with putting conflicting files in the index for your discard-undo work, you could pass in extra "conflicting" paths as a prop here ☝️
|
||
componentDidMount() { | ||
this.subscriptions.add( | ||
this.props.editor.onDidStopChanging(() => this.setState({})), |
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.
Change this to
.forceUpdate()
this.layer = props.editor.getDefaultMarkerLayer(); | ||
|
||
this.state = { | ||
conflicts: Conflict.allFromEditor(props.editor, this.layer, props.isRebase), |
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.
Make this a Set
dismissConflicts(conflicts) { | ||
const conflictSet = new Set(conflicts); | ||
this.setState((prevState, props) => { | ||
const newConflicts = prevState.conflicts.filter(conflict => !conflictSet.has(conflict)); |
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.
Use compare-sets
lib/views/staging-view.js
Outdated
onclick={this.props.abortMerge}> | ||
Abort Merge | ||
</button> | ||
) : null; |
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.
Instead, add a drop-down to resolve all files as ours/theirs
remainingConflicts={resolutionProgress.getRemaining(fullPath)} | ||
registerItemElement={this.registerItemElement} | ||
ondblclick={event => this.dblclickOnItem(event, mergeConflict)} | ||
oncontextmenu={event => this.contextMenuOnItem(event, mergeConflict)} |
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 resolve as ours/resolve as theirs as context menu options
for (let i = 0; i < data.mergeConflicts.length; i++) { | ||
const conflictPath = path.join(data.workingDirectoryPath, data.mergeConflicts[i].filePath); | ||
if (!openPaths.has(conflictPath) && this.props.resolutionProgress.getRemaining(conflictPath) === undefined) { | ||
const readStream = fs.createReadStream(conflictPath, {encoding: 'utf-8'}); |
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.
Remove the -
in utf-8
Changed the colors from the "random" site colors to the git colors. Should add a little more meaning:
That the "ours" changes are red might be a bit strong, but also makes some sense. Like picking only "your changes" and ignore the rest (remote) is somewhat dangerous and should only be done with caution. |
Hmm, yeah, I'm not as fond of that red, it feels too strong. I'm not sure what would be better, though - orange is blue's complement but that's already used for "modified," which feels right... I like the others though! |
Hmm now that I've used it a bit, the red seems okay to me 🤔 I trust your judgement, go with whatever looks right to you 😁 |
Is there a setting I can change if I want to disable this feature? |
Port a bunch of code from merge-conflicts to parse, mark, and resolve conflict markers within TextEditors.
DisplayMarker
on the banners, sides, and separators of each. Handle and test against weird recursive conflict cases.Decoration
component, like thePanel
andPaneItem
components, that maps the lifecycle of an Atom Decoration to that of a React component.RepositoryConflictController
to render a subcomponent for each openTextEditor
that corresponds to a merge conflict.EditorConflictController
to render a subcomponent for eachConflict
parsed out of a specificTextEditor
.ConflictController
to render a set ofDecorations
corresponding to each part of a specificConflict
.Repository
. Reset it when the merge is aborted or committed.GitPanelView
to show the resolution progress for each file.ConflictController
to resolve a conflict as ours, theirs, ours then theirs, or theirs then ours.github:*
commands.References #383.