void (@NotNull DefaultActionGroup group, @Nullable VirtualFile virtualFile, @NotNull List<? extends Charset> charsets, @NotNull Function<? super Charset, @NlsActions.ActionDescription String> descriptionSupplier) { for (final Charset charset : charsets) { AnAction action = new CharsetAction(charset.displayName(), null, EmptyIcon.ICON_16) { @Override public void actionPerformed(@NotNull AnActionEvent e) { chosen(virtualFile, charset); } @Override public void update(@NotNull AnActionEvent e) { super.update(e); String description = descriptionSupplier.fun(charset); Icon defer; if (virtualFile == null || virtualFile.isDirectory()) { defer = null; } else { NotNullLazyValue<CharSequence> myText = NotNullLazyValue.volatileLazy(()->LoadTextUtil.loadText(virtualFile)); NotNullLazyValue<byte[]> myBytes = NotNullLazyValue.volatileLazy(() -> { try { return virtualFile.contentsToByteArray(); } catch (IOException e1) { return ArrayUtilRt.EMPTY_BYTE_ARRAY; } }); defer = IconManager.getInstance().createDeferredIcon(null, new Pair<>(virtualFile, charset), pair -> { VirtualFile myFile = pair.getFirst(); Charset charset = pair.getSecond(); CharSequence text = myText.getValue(); byte[] bytes = myBytes.getValue(); EncodingUtil.Magic8 safeToReload = EncodingUtil.isSafeToReloadIn(myFile, text, bytes, charset); EncodingUtil.Magic8 safeToConvert; if (safeToReload == EncodingUtil.Magic8.ABSOLUTELY) { safeToConvert = EncodingUtil.Magic8.ABSOLUTELY; } else { safeToConvert = EncodingUtil.isSafeToConvertTo(myFile, text, bytes, charset); } return safeToReload == EncodingUtil.Magic8.ABSOLUTELY || safeToConvert == EncodingUtil.Magic8.ABSOLUTELY ? null : safeToReload == EncodingUtil.Magic8.WELL_IF_YOU_INSIST || safeToConvert == EncodingUtil.Magic8.WELL_IF_YOU_INSIST ? AllIcons.General.Warning : AllIcons.General.Error; }); } e.getPresentation().setIcon(defer); e.getPresentation().setDescription(description); } @Override public @NotNull ActionUpdateThread getActionUpdateThread() { return ActionUpdateThread.BGT; } }; group.add(action); } }