Fix refresh/undo for commands causing document saving

Since saving is asynchronous the scoped refresh/undo helper would do “cleanup” before the command ran and potentially made document changes.

Commands executed at a lower level (i.e. by editor_t via macros) presently still has this issue. This should be fixed when macros are refactored (this isn’t the only issue related to macros).

Closes #450.
This commit is contained in:
Allan Odgaard
2013-04-25 16:38:16 +07:00
parent 29aa65d5d9
commit bcc3e4c1fb
3 changed files with 53 additions and 1 deletions

View File

@@ -925,6 +925,41 @@ namespace
[DocumentSaveHelper trySaveDocuments:documentsToSave forWindow:self.window defaultDirectory:self.untitledSavePath completionHandler:nil];
}
- (void)bundleItemPreExec:(pre_exec::type)preExec completionHandler:(void(^)(BOOL success))callback
{
std::vector<document::document_ptr> documentsToSave;
switch(preExec)
{
case pre_exec::save_document:
{
if(_selectedDocument && (_selectedDocument->is_modified() || !_selectedDocument->is_on_disk()))
documentsToSave.push_back(_selectedDocument);
}
break;
case pre_exec::save_project:
{
for(auto document : _documents)
{
if(document->is_modified() && document->path() != NULL_STR)
documentsToSave.push_back(document);
}
}
break;
}
if(!documentsToSave.empty())
{
[DocumentSaveHelper trySaveDocuments:documentsToSave forWindow:self.window defaultDirectory:self.untitledSavePath completionHandler:^(BOOL success){
callback(success);
}];
}
else
{
callback(YES);
}
}
// ================
// = Window Title =
// ================

View File

@@ -24,6 +24,7 @@ enum OTVFontSmoothing : NSUInteger
@protocol OakTextViewDelegate <NSObject>
@optional
- (void)bundleItemPreExec:(pre_exec::type)preExec completionHandler:(void(^)(BOOL success))callback;
- (NSString*)scopeAttributes;
@end

View File

@@ -1104,7 +1104,23 @@ doScroll:
case bundles::kItemTypeCommand:
{
[self recordSelector:@selector(executeCommandWithOptions:) withArgument:ns::to_dictionary(item->plist())];
document::run(parse_command(item), document->buffer(), editor->ranges(), document);
auto command = parse_command(item);
if([self.delegate respondsToSelector:@selector(bundleItemPreExec:completionHandler:)])
{
[self.delegate bundleItemPreExec:command.pre_exec completionHandler:^(BOOL success){
if(success)
{
AUTO_REFRESH;
document::run(command, document->buffer(), editor->ranges(), document);
}
}];
}
else
{
command.pre_exec = pre_exec::nop;
document::run(command, document->buffer(), editor->ranges(), document);
}
}
break;