diff --git a/Frameworks/DocumentWindow/src/DocumentController.mm b/Frameworks/DocumentWindow/src/DocumentController.mm index af3e04e8..b61d6f7f 100644 --- a/Frameworks/DocumentWindow/src/DocumentController.mm +++ b/Frameworks/DocumentWindow/src/DocumentController.mm @@ -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 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 = // ================ diff --git a/Frameworks/OakTextView/src/OakTextView.h b/Frameworks/OakTextView/src/OakTextView.h index 0453b615..7515f17d 100644 --- a/Frameworks/OakTextView/src/OakTextView.h +++ b/Frameworks/OakTextView/src/OakTextView.h @@ -24,6 +24,7 @@ enum OTVFontSmoothing : NSUInteger @protocol OakTextViewDelegate @optional +- (void)bundleItemPreExec:(pre_exec::type)preExec completionHandler:(void(^)(BOOL success))callback; - (NSString*)scopeAttributes; @end diff --git a/Frameworks/OakTextView/src/OakTextView.mm b/Frameworks/OakTextView/src/OakTextView.mm index 6a00d940..24354adc 100644 --- a/Frameworks/OakTextView/src/OakTextView.mm +++ b/Frameworks/OakTextView/src/OakTextView.mm @@ -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;