IDEA-135191 Incremental search on a non-project triggers 'Non-project files access' dialog when it shouldn't

Reapplied original fix for IDEA-113468, while allowing some custom typing handlers to run outside of command/write action scope.
This commit is contained in:
Dmitry Batrak
2015-05-12 14:12:00 +03:00
parent e38677cb89
commit e4dbca8a77
4 changed files with 67 additions and 45 deletions
@@ -37,7 +37,6 @@ import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.fileTypes.LanguageFileType;
@@ -143,9 +142,6 @@ public class TypedHandler extends TypedActionHandlerBase {
}
if (!CodeInsightUtilBase.prepareEditorForWrite(originalEditor)) return;
if (!FileDocumentManager.getInstance().requestWriting(originalEditor.getDocument(), project)) {
return;
}
final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
final Document originalDocument = originalEditor.getDocument();
@@ -40,7 +40,6 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorModificationUtil;
import com.intellij.openapi.editor.actionSystem.TypedActionHandler;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
@@ -68,7 +67,7 @@ public class LookupTypedHandler extends TypedActionHandlerBase {
return;
}
if (!CodeInsightUtilBase.prepareEditorForWrite(originalEditor) || !FileDocumentManager.getInstance().requestWriting(originalEditor.getDocument(), project)) {
if (!CodeInsightUtilBase.prepareEditorForWrite(originalEditor)) {
return;
}
@@ -92,7 +92,7 @@ public class IncrementalSearchHandler {
EditorActionManager actionManager = EditorActionManager.getInstance();
TypedAction typedAction = actionManager.getTypedAction();
typedAction.setupHandler(new MyTypedHandler(typedAction.getHandler()));
typedAction.setupRawHandler(new MyTypedHandler(typedAction.getRawHandler()));
actionManager.setActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE, new BackSpaceHandler(actionManager.getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE)));
actionManager.setActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_UP, new UpHandler(actionManager.getActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_UP)));
@@ -23,7 +23,6 @@ import com.intellij.openapi.command.UndoConfirmationPolicy;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,11 +32,14 @@ import org.jetbrains.annotations.Nullable;
* @see EditorActionManager#getTypedAction()
*/
public class TypedAction {
@NotNull
private TypedActionHandler myRawHandler;
private TypedActionHandler myHandler;
private boolean myHandlersLoaded;
public TypedAction() {
myHandler = new Handler();
myRawHandler = new DefaultRawHandler();
}
private void ensureHandlersLoaded() {
@@ -55,11 +57,6 @@ public class TypedAction {
if (editor.isViewer()) return;
Document doc = editor.getDocument();
Project project = CommonDataKeys.PROJECT.getData(dataContext);
if (!FileDocumentManager.getInstance().requestWriting(doc, project)) {
return;
}
doc.startGuardedBlockChecking();
try {
final String str = String.valueOf(charTyped);
@@ -99,43 +96,73 @@ public class TypedAction {
return tmp;
}
public final void actionPerformed(@Nullable final Editor editor, final char charTyped, final DataContext dataContext) {
if (editor == null) return;
Runnable command = new TypingCommand(editor, charTyped, dataContext);
CommandProcessor.getInstance().executeCommand(CommonDataKeys.PROJECT.getData(dataContext), command, "", editor.getDocument(), UndoConfirmationPolicy.DEFAULT, editor.getDocument());
/**
* Gets the current 'raw' typing handler.
*
* @see #setupRawHandler(TypedActionHandler)
*/
@NotNull
public TypedActionHandler getRawHandler() {
return myRawHandler;
}
private class TypingCommand implements Runnable {
private final Editor myEditor;
private final char myCharTyped;
private final DataContext myDataContext;
public TypingCommand(Editor editor, char charTyped, DataContext dataContext) {
myEditor = editor;
myCharTyped = charTyped;
myDataContext = dataContext;
}
/**
* Replaces current 'raw' typing handler with the specified handler. The handler should pass unprocessed typing to the
* previously registered 'raw' handler.
* <p>
* 'Raw' handler is a handler directly invoked by the code which handles typing in editor. Default 'raw' handler
* performs some generic logic that has to be done on typing (like checking whether file has write access, creating a command
* instance for undo subsystem, initiating write action, etc), but delegates to 'normal' handler for actual typing logic.
*
* @param handler the handler to set.
* @return the previously registered handler.
*
* @see #getRawHandler()
* @see #getHandler()
* @see #setupHandler(TypedActionHandler)
*/
@NotNull
public TypedActionHandler setupRawHandler(@NotNull TypedActionHandler handler) {
TypedActionHandler tmp = myRawHandler;
myRawHandler = handler;
return tmp;
}
public final void actionPerformed(@Nullable final Editor editor, final char charTyped, final DataContext dataContext) {
if (editor == null) return;
myRawHandler.execute(editor, charTyped, dataContext);
}
private class DefaultRawHandler implements TypedActionHandler {
@Override
public void run() {
ApplicationManager.getApplication().runWriteAction(new DocumentRunnable(myEditor.getDocument(), myEditor.getProject()) {
@Override
public void run() {
Document doc = myEditor.getDocument();
doc.startGuardedBlockChecking();
try {
getHandler().execute(myEditor, myCharTyped, myDataContext);
public void execute(@NotNull final Editor editor, final char charTyped, @NotNull final DataContext dataContext) {
CommandProcessor.getInstance().executeCommand(
CommonDataKeys.PROJECT.getData(dataContext),
new Runnable() {
@Override
public void run() {
if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), editor.getProject())) {
return;
}
ApplicationManager.getApplication().runWriteAction(new DocumentRunnable(editor.getDocument(), editor.getProject()) {
@Override
public void run() {
Document doc = editor.getDocument();
doc.startGuardedBlockChecking();
try {
getHandler().execute(editor, charTyped, dataContext);
}
catch (ReadOnlyFragmentModificationException e) {
EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(doc).handle(e);
}
finally {
doc.stopGuardedBlockChecking();
}
}
});
}
catch (ReadOnlyFragmentModificationException e) {
EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(doc).handle(e);
}
finally {
doc.stopGuardedBlockChecking();
}
}
});
},
"", editor.getDocument(), UndoConfirmationPolicy.DEFAULT, editor.getDocument());
}
}
}