diff --git a/plugins/editorconfig/resources/META-INF/plugin.xml b/plugins/editorconfig/resources/META-INF/plugin.xml index ba205a8f88ea..ff8e2fe6e821 100644 --- a/plugins/editorconfig/resources/META-INF/plugin.xml +++ b/plugins/editorconfig/resources/META-INF/plugin.xml @@ -60,7 +60,6 @@ - +usage.descriptive.name.site={0} in {1} +usage.descriptive.name.unknown= +usage.node.text={0} {1} +usage.node.unknown= + +# Create file +create.file.title=.editorconfig file +create.file.description=Create .editorconfig file + +# Descriptors +descriptor.unset.documentation=Ignore all the above declarations and use editor defaults + +# Notifications +notification.rename.message=Editorconfig standard requires file to be called '.editorconfig' +notification.action.rename=Rename +notification.action.hide.once=Hide notification +notification.action.hide.forever=Don't show again +notification.error.file.already.exists=Could not rename: file already exists +notification.error.ioexception=Could not rename: IOException {0} +notification.encoding.message=Standard requires .editorconfig file to be encoded in UTF-8 +notification.action.convert=Convert to UTF-8 + +# Completion +completion.all.required.declarations={0}, all required + advertisement.text=Current indent options are overridden by .editorconfig config.title=EditorConfig config.enable=Enable EditorConfig support @@ -5,4 +203,5 @@ config.warning=EditorConfig may override the IDE code style settings config.export=Export action.disable=Disable EditorConfig +action.open.file=Open {0} File... disabled.notification=EditorConfig was disabled for the project. \ No newline at end of file diff --git a/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorConfigIndentOptionsProvider.java b/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorConfigIndentOptionsProvider.java index c48e6df15ec9..f57312e18abb 100644 --- a/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorConfigIndentOptionsProvider.java +++ b/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorConfigIndentOptionsProvider.java @@ -20,8 +20,8 @@ import com.intellij.psi.codeStyle.FileIndentOptionsProvider; import com.intellij.util.containers.ContainerUtil; import org.editorconfig.Utils; import org.editorconfig.core.EditorConfig; +import org.editorconfig.language.messages.EditorConfigBundle; import org.editorconfig.plugincomponents.SettingsProviderComponent; -import org.editorconfig.settings.EditorConfigBundle; import org.editorconfig.settings.EditorConfigSettings; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -69,6 +69,8 @@ public class EditorConfigIndentOptionsProvider extends FileIndentOptionsProvider final String indentStyle = Utils.configValueForKey(outPairs, indentStyleKey); final IndentOptions indentOptions = (IndentOptions)settings.getIndentOptions(file.getFileType()).clone(); if (applyIndentOptions(project, indentOptions, indentSize, continuationIndentSize, tabWidth, indentStyle, file.getCanonicalPath())) { + // Start retrieving parent files here + EditorConfigNavigationActionsFactory.getParentFiles(file, project); indentOptions.setOverrideLanguageOptions(true); return indentOptions; } @@ -184,6 +186,7 @@ public class EditorConfigIndentOptionsProvider extends FileIndentOptionsProvider final Project project = file.getProject(); if (isEditorConfigOptions(indentOptions)) { List actions = ContainerUtil.newArrayList(); + actions.addAll(EditorConfigNavigationActionsFactory.getNavigationActions(file)); actions.add( DumbAwareAction.create( EditorConfigBundle.message("action.disable"), diff --git a/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorConfigNavigationActionsFactory.java b/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorConfigNavigationActionsFactory.java new file mode 100644 index 000000000000..161722eff4cc --- /dev/null +++ b/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorConfigNavigationActionsFactory.java @@ -0,0 +1,46 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.editorconfig.configmanagement; + +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.NavigatablePsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.util.containers.ContainerUtil; +import org.editorconfig.language.messages.EditorConfigBundle; +import org.editorconfig.language.psi.EditorConfigPsiFile; +import org.editorconfig.language.services.EditorConfigFileHierarchyService; +import org.editorconfig.language.services.EditorConfigServiceLoaded; +import org.editorconfig.language.services.EditorConfigServiceResult; +import org.editorconfig.language.util.EditorConfigPresentationUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +public class EditorConfigNavigationActionsFactory { + @NotNull + public static List getNavigationActions(@NotNull final PsiFile file) { + final List actions = ContainerUtil.newArrayList(); + final List parentFiles = getParentFiles(file.getVirtualFile(), file.getProject()); + for (EditorConfigPsiFile parentFile : parentFiles) { + final NavigatablePsiElement target = parentFile.findRelevantNavigatable(); + actions.add(DumbAwareAction.create( + getActionName(parentFile, parentFiles.size() > 1), + event -> target.navigate(true))); + } + return actions; + } + + private static String getActionName(@NotNull EditorConfigPsiFile file, boolean withFolder) { + return EditorConfigBundle.message("action.open.file", EditorConfigPresentationUtil.INSTANCE.getFileName(file, withFolder)); + } + + @NotNull + static List getParentFiles(@NotNull final VirtualFile virtualFile, @NotNull final Project project) { + final EditorConfigFileHierarchyService hierarchyService = EditorConfigFileHierarchyService.Companion.getInstance(project); + final EditorConfigServiceResult serviceResult = hierarchyService.getParentEditorConfigFiles(virtualFile); + return serviceResult instanceof EditorConfigServiceLoaded ? + ((EditorConfigServiceLoaded)serviceResult).getList() : Collections.emptyList(); + } +} diff --git a/plugins/editorconfig/src/org/editorconfig/language/messages/EditorConfigBundle.kt b/plugins/editorconfig/src/org/editorconfig/language/messages/EditorConfigBundle.kt index ef93e91ca727..55122971fb46 100644 --- a/plugins/editorconfig/src/org/editorconfig/language/messages/EditorConfigBundle.kt +++ b/plugins/editorconfig/src/org/editorconfig/language/messages/EditorConfigBundle.kt @@ -10,7 +10,7 @@ import java.util.* object EditorConfigBundle { @NonNls - const val BUNDLE: String = "org.editorconfig.language.messages.EditorConfigBundle" + const val BUNDLE: String = "messages.EditorConfigBundle" private var bundleReference: Reference? = null @@ -20,9 +20,15 @@ object EditorConfigBundle { @Suppress("RemoveRedundantSpreadOperator") operator fun get(@PropertyKey(resourceBundle = BUNDLE) key: String) = get(key, *emptyArray()) + @JvmStatic + fun message(key : String) = EditorConfigBundle[key] + + @JvmStatic + fun message(key: String, param: String) = EditorConfigBundle.get(key, param) + private fun getBundle() = SoftReference.dereference(bundleReference) ?: run { val bundle = ResourceBundle.getBundle(BUNDLE) bundleReference = SoftReference(bundle) bundle } -} +} \ No newline at end of file diff --git a/plugins/editorconfig/src/org/editorconfig/language/messages/EditorConfigBundle.properties b/plugins/editorconfig/src/org/editorconfig/language/messages/EditorConfigBundle.properties deleted file mode 100644 index 89cb51c580e0..000000000000 --- a/plugins/editorconfig/src/org/editorconfig/language/messages/EditorConfigBundle.properties +++ /dev/null @@ -1,200 +0,0 @@ -# Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - -file.type.description=File containing settings for editor - -# Groups -editorconfig.inspection.group=EditorConfig -editorconfig.intention.group=EditorConfig -# Annotator errors: -annotator.error.key.dangling-dot=Dangling dot -annotator.error.dangling.key=This option lacks value -annotator.error.multiple-dots=Successive dots -annotator.error.illegal.char.escape=Illegal char escape -annotator.error.option.suspicious.line.break=Line break is not allowed inside option - -# Section inspections -inspection.section.uniqueness.name=Uniqueness of EditorConfig section -inspection.section.uniqueness.message=''{0}'' is declared more than once in current file -inspection.section.uniqueness.complex.message=Defines same pattern as ''{0}'' - -# General inspections -inspection.element.deprecated.name=Deprecation of EditorConfig element - -# Option inspections -inspection.option.shadowed.name=Meaningfulness of EditorConfig option -inspection.option.shadowed.message=Option shadowed -inspection.option.shadowing.name=Uniqueness of occurrence of EditorConfig option -inspection.option.shadowing.message=Shadows earlier declaration -inspection.option.redundant.name=Option redundancy -inspection.option.redundant.singular.message=This option duplicates parent and can be removed -inspection.option.redundant.plural.message=This option duplicates all parents and can be removed -inspection.option.suspicious.line.break.name=Line break in option - -# Key inspections -inspection.key.correctness.name=Correctness of EditorConfig key -inspection.key.correctness.message=Unknown key - -# Value identifier inspections -inspection.value.correctness.name=Correctness of EditorConfig value -inspection.value.correctness.message=''{0}'' not allowed here -inspection.value.uniqueness.name=Uniqueness of value in list -inspection.value.uniqueness.message=This list does not allow duplicate values - -# Reference inspections -inspection.reference.correctness.name=Correctness of identifier reference -inspection.reference.unresolved.message=Unresolved reference -inspection.reference.type.mismatch.message=Type mismatch. Expected: {0}, got {1} - -# Declaration inspections -inspection.declaration.unused.name=Unused declaration -inspection.declaration.unused.message=Unused declaration -inspection.declaration.missing.name=Missing required declaration -inspection.declaration.missing.plural.message={0} requires {1} more declarations -inspection.declaration.missing.singular.message={0} requires one more declaration - -# Value list inspections -inspection.value.list.acceptability.name=List unexpected -inspection.value.list.acceptability.message=List of values is not allowed here -inspection.value.list.comma.unexpected.name=Unexpected comma -inspection.value.list.comma.unexpected.message=There should be no comma here -inspection.value.pair.acceptability.name=Pair unexpected -inspection.value.pair.acceptability.message=Pair of values is not allowed here - -# Root declaration inspections -inspection.root-declaration.uniqueness.name=Uniqueness of top-level declaration -inspection.root-declaration.uniqueness.message=Only one top-level declaration is allowed -inspection.root-declaration.correctness.name=Correctness of root declaration -inspection.root-declaration.correctness.message=Only 'root=true' is allowed as top-level declaration - -# Header inspections -inspection.pattern-enumeration.redundant.name=Redundant pattern enumeration -inspection.pattern-enumeration.redundant.message=This pattern enumeration contains less than two patterns, so braces should be removed -inspection.space.in.header.name=Space in header -inspection.space.in.header.message=Space in header is likely to be a typo -inspection.no-matching-files.name=No matching files -inspection.no-matching-files.message=No files under ''{0}'' folder match this pattern -inspection.header.empty.name=Empty header -inspection.header.empty.message=Empty header -inspection.header.many.wildcards.name=Too many wildcards -inspection.header.many.wildcards.message=Too many wildcards -inspection.header.partially.overridden.name=Partial override -inspection.header.partially.overridden.message=Partial override - -# Pattern inspections -inspection.pattern.redundant.name=Redundancy of pattern enumeration -inspection.pattern.redundant.message=This pattern is subcase of {0} and can be removed -inspection.pattern.redundant.to.union.message=This pattern is subcase of union of others and can be removed -inspection.pattern.duplicate.message=Duplicate pattern -inspection.pattern.double-asterisk-sibling.name=Wildcard redundancy -inspection.pattern.double-asterisk-sibling.message=This wildcard pattern neighbours ''**'', which makes it redundant - -# Charclass inspections -inspection.charclass.duplicate.name=Duplicate letter in char class -inspection.charclass.duplicate.message=Duplicate letter in char class -inspection.charclass.redundant.name=Redundant char class -inspection.charclass.redundant.message=Char class can be converted to plain pattern - -# Section inspections -inspection.section.emptiness.name=Emptiness of EditorConfig section -inspection.section.emptiness.message=This section is empty - -# Quickfixes -quickfix.section.remove.description=Remove section -quickfix.section.merge-duplicate.description=Merge duplicate sections -quickfix.option.remove.description=Remove entry -quickfix.value.remove.description=Remove value -quickfix.value.list.remove.others=Remove other values -quickfix.root-declaration.remove.description=Remove declaration -quickfix.root-declaration.replace-with-valid.description=Replace with correct declaration -quickfix.pattern-enumeration.redundant.remove-braces.description=Remove braces -quickfix.charclass.sanitize.description=Simplify char class -quickfix.charclass.convert.to.plain.pattern.description=Convert to plain pattern -quickfix.header-element.remove.description=Remove redundant element -quickfix.header.remove.spaces.description=Remove spaces -quickfix.declaration.add-required.description=Add required declarations -quickfix.values.list.cleanup.description=Clean up list -quickfix.header.insert.star.description=Insert star -quickfix.deprecated.element.remove=Remove element - -# Intention actions -intention.invert-option-value=Invert -intention.add-declaration-part=Add declaration part - -# Guttermark messages -message.overriding.title=Please, select option -message.overriding.find-usages-title=Options overridden by {0} -message.overriding.element=Overrides {0} -message.overriding.multiple=Overrides several options -message.overridden.title=Please, select override -message.overridden.find-usages-title=Overrides of {0} in {1} -message.overridden.element=Overridden in {0} -message.overridden.multiple=Overridden in several places - -message.header.override.title=Please, select header - -message.header.partially-overriding.find-usages-title=Header partially overridden by {0} -message.header.partially-overriding.element=Partially overrides {0} -message.header.partially-overriding.multiple=Partially overrides several headers - -message.header.overriding.find-usages-title=Headers overridden by {0} -message.header.overriding.element=Overrides {0} -message.header.overriding.multiple=Overrides several headers - -message.header.partially-overridden.find-usages-title=Headers partially overriding {0} -message.header.partially-overridden.element=Partially overridden by {0} -message.header.partially-overridden.multiple=Partially overridden in several places - -message.header.overridden.find-usages-title=Headers overriding {0} -message.header.overridden.element=Overridden by {0} -message.header.overridden.multiple=Overridden in several places - -# Annotator -annotator.illegal.char.escape=Illegal char escape - -# Color settings page -color.settings.property.key=Property key -color.settings.property.key.description=Qualified key part -color.settings.property.value=Property value -color.settings.pattern=Pattern -color.settings.special.symbol=Special symbol -color.settings.valid.char.escape=Valid char escape -color.settings.invalid.char.escape=Invalid char escape -color.settings.separator=Separator -color.settings.brace=Brace -color.settings.bracket=Bracket -color.settings.comma=Comma -color.settings.identifier=Identifier -color.settings.comment=Comment - -# Find usages -usage.type.option.key=Key {0} in {1} -usage.type.identifier=Identifier {0} in {1} -usage.type.constant=Constant {0} in {1} -usage.type.unknown= -usage.descriptive.name.site={0} in {1} -usage.descriptive.name.unknown= -usage.node.text={0} {1} -usage.node.unknown= - -# Create file -create.file.title=.editorconfig file -create.file.description=Create .editorconfig file - -# Descriptors -descriptor.unset.documentation=Ignore all the above declarations and use editor defaults - -# Notifications -notification.rename.message=Editorconfig standard requires file to be called '.editorconfig' -notification.action.rename=Rename -notification.action.hide.once=Hide notification -notification.action.hide.forever=Don't show again -notification.error.file.already.exists=Could not rename: file already exists -notification.error.ioexception=Could not rename: IOException {0} -notification.encoding.message=Standard requires .editorconfig file to be encoded in UTF-8 -notification.action.convert=Convert to UTF-8 - -# Completion -completion.all.required.declarations={0}, all required - -# Widget -widget.editorconfig.affected=EditorConfig file affects editor behaviour diff --git a/plugins/editorconfig/src/org/editorconfig/language/psi/EditorConfigPsiFile.kt b/plugins/editorconfig/src/org/editorconfig/language/psi/EditorConfigPsiFile.kt index 534d4285e975..ae11f715b933 100644 --- a/plugins/editorconfig/src/org/editorconfig/language/psi/EditorConfigPsiFile.kt +++ b/plugins/editorconfig/src/org/editorconfig/language/psi/EditorConfigPsiFile.kt @@ -7,6 +7,7 @@ import com.intellij.psi.util.PsiTreeUtil import org.editorconfig.language.EditorConfigLanguage import org.editorconfig.language.filetype.EditorConfigFileConstants import org.editorconfig.language.filetype.EditorConfigFileType +import org.editorconfig.language.util.matches class EditorConfigPsiFile(viewProvider: FileViewProvider) : PsiFileBase(viewProvider, EditorConfigLanguage) { override fun getFileType() = EditorConfigFileType @@ -19,4 +20,11 @@ class EditorConfigPsiFile(viewProvider: FileViewProvider) : PsiFileBase(viewProv val sections: List get() = PsiTreeUtil.getChildrenOfTypeAsList(this, EditorConfigSection::class.java) + + fun findRelevantNavigatable() = + sections.lastOrNull { section -> + val header = section.header + if (header.isValidGlob) header matches virtualFile + else false + } ?: this } diff --git a/plugins/editorconfig/src/org/editorconfig/language/services/EditorConfigFileHierarchyService.kt b/plugins/editorconfig/src/org/editorconfig/language/services/EditorConfigFileHierarchyService.kt index b54fec9f7f03..88d994316dde 100644 --- a/plugins/editorconfig/src/org/editorconfig/language/services/EditorConfigFileHierarchyService.kt +++ b/plugins/editorconfig/src/org/editorconfig/language/services/EditorConfigFileHierarchyService.kt @@ -4,11 +4,7 @@ package org.editorconfig.language.services import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile -import com.intellij.util.messages.Topic import org.editorconfig.language.psi.EditorConfigPsiFile -import org.editorconfig.language.widget.EditorConfigNotificationServiceListener - -val EditorConfigNotificationTopic = Topic("EDITORCONFIG_VFS_NOTIFICATION_TOPIC", EditorConfigNotificationServiceListener::class.java) sealed class EditorConfigServiceResult data class EditorConfigServiceLoaded(val list: List) : EditorConfigServiceResult() diff --git a/plugins/editorconfig/src/org/editorconfig/language/services/impl/EditorConfigFileHierarchyServiceImpl.kt b/plugins/editorconfig/src/org/editorconfig/language/services/impl/EditorConfigFileHierarchyServiceImpl.kt index dc72bd0b6724..d99bd8c1d1ab 100644 --- a/plugins/editorconfig/src/org/editorconfig/language/services/impl/EditorConfigFileHierarchyServiceImpl.kt +++ b/plugins/editorconfig/src/org/editorconfig/language/services/impl/EditorConfigFileHierarchyServiceImpl.kt @@ -16,6 +16,7 @@ import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.openapi.vfs.newvfs.BulkFileListener import com.intellij.openapi.vfs.newvfs.events.VFileEvent import com.intellij.psi.PsiManager +import com.intellij.psi.codeStyle.CodeStyleSettingsManager import com.intellij.reference.SoftReference import com.intellij.util.concurrency.SequentialTaskExecutor import com.intellij.util.containers.FixedHashMap @@ -31,7 +32,7 @@ import java.lang.ref.Reference class EditorConfigFileHierarchyServiceImpl( private val manager: PsiManager, private val application: Application, - project: Project + private val project: Project ) : EditorConfigFileHierarchyService, BulkFileListener, RegistryValueListener.Adapter() { private val taskExecutor = SequentialTaskExecutor .createSequentialApplicationPoolExecutor("editorconfig.notification.vfs.update.executor") @@ -46,9 +47,9 @@ class EditorConfigFileHierarchyServiceImpl( Registry.get(EditorConfigRegistry.EDITORCONFIG_STOP_AT_PROJECT_ROOT_KEY).addListener(this, project) } - private fun updateHandlers() { + private fun updateHandlers(project: Project) { application.assertIsDispatchThread() - application.messageBus.syncPublisher(EditorConfigNotificationTopic).editorConfigChanged() + CodeStyleSettingsManager.getInstance(project).fireCodeStyleSettingsChanged(null) } // method of BulkFileListener @@ -65,7 +66,7 @@ class EditorConfigFileHierarchyServiceImpl( affectingFilesCache.clear() } - updateHandlers() + updateHandlers(project) } } @@ -98,7 +99,7 @@ class EditorConfigFileHierarchyServiceImpl( affectingFilesCache[virtualFile] = SoftReference(affectingFiles) } - updateHandlers() + updateHandlers(project) }.submit(taskExecutor) } diff --git a/plugins/editorconfig/src/org/editorconfig/language/widget/EditorConfigNotificationServiceListener.kt b/plugins/editorconfig/src/org/editorconfig/language/widget/EditorConfigNotificationServiceListener.kt deleted file mode 100644 index 3dc902009db4..000000000000 --- a/plugins/editorconfig/src/org/editorconfig/language/widget/EditorConfigNotificationServiceListener.kt +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.editorconfig.language.widget - -interface EditorConfigNotificationServiceListener { - fun editorConfigChanged() -} diff --git a/plugins/editorconfig/src/org/editorconfig/language/widget/EditorConfigPopupStep.kt b/plugins/editorconfig/src/org/editorconfig/language/widget/EditorConfigPopupStep.kt deleted file mode 100644 index 9cfd4c163e7e..000000000000 --- a/plugins/editorconfig/src/org/editorconfig/language/widget/EditorConfigPopupStep.kt +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.editorconfig.language.widget - -import com.intellij.openapi.ui.popup.PopupStep -import com.intellij.openapi.ui.popup.util.BaseListPopupStep -import com.intellij.openapi.vfs.VirtualFile -import org.editorconfig.language.psi.EditorConfigPsiFile -import org.editorconfig.language.util.EditorConfigPresentationUtil -import org.editorconfig.language.util.matches - -class EditorConfigPopupStep( - files: List, - private val virtualFile: VirtualFile -) : BaseListPopupStep(null, files) { - override fun getTextFor(value: EditorConfigPsiFile) = - EditorConfigPresentationUtil.getFileName(value, true) - - override fun onChosen(selectedValue: EditorConfigPsiFile, finalChoice: Boolean): PopupStep<*>? { - if (finalChoice) { - return doFinalStep { - findRelevantNavigatable(selectedValue).navigate(true) - } - } - - return PopupStep.FINAL_CHOICE - } - - private fun findRelevantNavigatable(file: EditorConfigPsiFile) = - file.sections.lastOrNull { section -> - val header = section.header - if (header.isValidGlob) header matches virtualFile - else false - } ?: file -} diff --git a/plugins/editorconfig/src/org/editorconfig/language/widget/EditorConfigStatusBarWidget.kt b/plugins/editorconfig/src/org/editorconfig/language/widget/EditorConfigStatusBarWidget.kt deleted file mode 100644 index d2a9e216cd83..000000000000 --- a/plugins/editorconfig/src/org/editorconfig/language/widget/EditorConfigStatusBarWidget.kt +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.editorconfig.language.widget - -import com.intellij.openapi.actionSystem.CommonDataKeys -import com.intellij.openapi.actionSystem.DataContext -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.diagnostic.logger -import com.intellij.openapi.project.Project -import com.intellij.openapi.ui.popup.JBPopupFactory -import com.intellij.openapi.ui.popup.ListPopup -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.openapi.wm.impl.status.EditorBasedStatusBarPopup -import icons.EditorconfigIcons -import org.editorconfig.language.messages.EditorConfigBundle -import org.editorconfig.language.services.* - -class EditorConfigStatusBarWidget(project: Project) : EditorBasedStatusBarPopup(project), EditorConfigNotificationServiceListener { - private val service = EditorConfigFileHierarchyService.getInstance(project) - - init { - ApplicationManager - .getApplication() - .messageBus - .connect() - .subscribe(EditorConfigNotificationTopic, this) - } - - private fun getApplicableFiles(file: VirtualFile): EditorConfigServiceResult { - val start = System.currentTimeMillis() - val result = service.getParentEditorConfigFiles(file) - val end = System.currentTimeMillis() - val duration = end - start - if (duration > 50) { - Log.warn("Performance warning: EditorConfigFileHierarchyService took too long to answer ($duration ms)") - } - - return result - } - - override fun getWidgetState(file: VirtualFile?): WidgetState { - file ?: return WidgetState.HIDDEN - val serviceAnswer = getApplicableFiles(file) - return when (serviceAnswer) { - is EditorConfigServiceLoading -> WidgetState.HIDDEN - is EditorConfigServiceLoaded -> { - if (serviceAnswer.list.isEmpty()) WidgetState.HIDDEN - else EditorConfigWidgetState() - } - } - } - - override fun editorConfigChanged() = update() - - // Should I register service callback here? - override fun registerCustomListeners() = Unit - - override fun ID() = "edeitorconfig.affects.codestyle.status.bar.widget" - - override fun createPopup(context: DataContext): ListPopup? { - val virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(context) ?: return null - val serviceAnswer = getApplicableFiles(virtualFile) - val files = when (serviceAnswer) { - is EditorConfigServiceLoading -> return null - is EditorConfigServiceLoaded -> serviceAnswer.list - } - - if (files.isEmpty()) return null - val step = EditorConfigPopupStep(files, virtualFile) - val factory = JBPopupFactory.getInstance() - return factory.createListPopup(step) - } - - override fun createInstance(project: Project) = - EditorConfigStatusBarWidget(project) - - private class EditorConfigWidgetState - : WidgetState(EditorConfigBundle["widget.editorconfig.affected"], null, true) { - init { - setIcon(EditorconfigIcons.Editorconfig) - } - } - - private companion object { - private val Log = logger() - } -} diff --git a/plugins/editorconfig/src/org/editorconfig/language/widget/EditorConfigStatusBarWidgetProvider.kt b/plugins/editorconfig/src/org/editorconfig/language/widget/EditorConfigStatusBarWidgetProvider.kt deleted file mode 100644 index f0519ae9ad9f..000000000000 --- a/plugins/editorconfig/src/org/editorconfig/language/widget/EditorConfigStatusBarWidgetProvider.kt +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.editorconfig.language.widget - -import com.intellij.openapi.project.Project -import com.intellij.openapi.wm.StatusBarWidgetProvider - -class EditorConfigStatusBarWidgetProvider : StatusBarWidgetProvider { - override fun getWidget(project: Project) = EditorConfigStatusBarWidget(project) -} diff --git a/plugins/editorconfig/src/org/editorconfig/settings/EditorConfigBundle.java b/plugins/editorconfig/src/org/editorconfig/settings/EditorConfigBundle.java deleted file mode 100644 index 6f86514c7f60..000000000000 --- a/plugins/editorconfig/src/org/editorconfig/settings/EditorConfigBundle.java +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.editorconfig.settings; - -import com.intellij.CommonBundle; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.PropertyKey; - -import java.lang.ref.Reference; -import java.lang.ref.SoftReference; -import java.util.ResourceBundle; - -public class EditorConfigBundle { - - public static String message(@NotNull @PropertyKey(resourceBundle = EDITOR_CONFIG_BUNDLE) String key, @NotNull Object... params) { - return CommonBundle.message(getBundle(), key, params); - } - - private static Reference ourBundle; - @NonNls public static final String EDITOR_CONFIG_BUNDLE = "messages.EditorConfigBundle"; - - private EditorConfigBundle() { - } - - @SuppressWarnings("Duplicates") - private static ResourceBundle getBundle() { - ResourceBundle bundle = com.intellij.reference.SoftReference.dereference(ourBundle); - if (bundle == null) { - bundle = ResourceBundle.getBundle(EDITOR_CONFIG_BUNDLE); - ourBundle = new SoftReference<>(bundle); - } - return bundle; - } -} diff --git a/plugins/editorconfig/src/org/editorconfig/settings/EditorConfigConfigurable.java b/plugins/editorconfig/src/org/editorconfig/settings/EditorConfigConfigurable.java index d9c50392ffb9..5ff529487dc5 100644 --- a/plugins/editorconfig/src/org/editorconfig/settings/EditorConfigConfigurable.java +++ b/plugins/editorconfig/src/org/editorconfig/settings/EditorConfigConfigurable.java @@ -15,6 +15,7 @@ import com.intellij.util.messages.MessageBus; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; import org.editorconfig.Utils; +import org.editorconfig.language.messages.EditorConfigBundle; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable;