mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[Inlay Text Hints] added action to report tourbled inline hints
This commit is contained in:
+8
-1
@@ -21,6 +21,7 @@ import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorCustomElementRenderer;
|
||||
import com.intellij.openapi.editor.EditorCustomTextElementRenderer;
|
||||
import com.intellij.openapi.editor.Inlay;
|
||||
import com.intellij.openapi.editor.impl.FontInfo;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
@@ -124,7 +125,7 @@ public class ParameterHintsPresentationManager implements Disposable {
|
||||
return metrics;
|
||||
}
|
||||
|
||||
private static class MyRenderer implements EditorCustomElementRenderer {
|
||||
private static class MyRenderer implements EditorCustomTextElementRenderer {
|
||||
private String myText;
|
||||
private int startWidth;
|
||||
private int steps;
|
||||
@@ -147,6 +148,12 @@ public class ParameterHintsPresentationManager implements Disposable {
|
||||
step = 1;
|
||||
steps = Math.max(1, Math.abs(endWidth - startWidth) / metrics.charWidth('a') / ANIMATION_CHARS_PER_STEP);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return myText;
|
||||
}
|
||||
|
||||
public boolean nextStep() {
|
||||
return ++step <= steps;
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.reporting
|
||||
|
||||
import com.intellij.codeInsight.hint.HintManager
|
||||
import com.intellij.openapi.actionSystem.*
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.components.ApplicationComponent
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.EditorCustomTextElementRenderer
|
||||
import com.intellij.openapi.editor.Inlay
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import java.io.File
|
||||
|
||||
|
||||
class InlineHintReporterRegistration : ApplicationComponent {
|
||||
|
||||
override fun getComponentName() = "Inline Hints Reporter Initializer"
|
||||
|
||||
override fun initComponent() {
|
||||
if (!isHintsEnabled()) return
|
||||
|
||||
val manager = ActionManager.getInstance()
|
||||
val action = ReportMissingOrExcessiveInlineHint()
|
||||
manager.registerAction("ReportMissingOrExcessiveInlineHint", action)
|
||||
|
||||
val group = manager.getAction("EditorPopupMenu") as DefaultActionGroup
|
||||
group.add(action)
|
||||
}
|
||||
|
||||
override fun disposeComponent() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ReportMissingOrExcessiveInlineHint : AnAction() {
|
||||
|
||||
private val text = "Report Missing or Excessive Inline Hint"
|
||||
private val description = "Text line at caret will be anonymously reported to our servers"
|
||||
|
||||
init {
|
||||
val presentation = templatePresentation
|
||||
presentation.text = text
|
||||
presentation.description = description
|
||||
}
|
||||
|
||||
private val recorderId = "inline-hints-reports"
|
||||
private val file = File(PathManager.getTempPath(), recorderId)
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
if (!isHintsEnabled()) return
|
||||
val editor = CommonDataKeys.EDITOR.getData(e.dataContext) ?: return
|
||||
|
||||
val range = getCurrentLineRange(editor)
|
||||
if (editor.getInlays(range).isNotEmpty()) {
|
||||
e.presentation.isEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val editor = CommonDataKeys.EDITOR.getData(e.dataContext)!!
|
||||
val document = editor.document
|
||||
|
||||
val range = getCurrentLineRange(editor)
|
||||
val inlays = editor.getInlays(range)
|
||||
|
||||
if (inlays.isNotEmpty()) {
|
||||
val line = document.getText(range)
|
||||
reportInlays(line.trim(), inlays)
|
||||
showHint(editor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun reportInlays(text: String, inlays: List<Inlay>) {
|
||||
val hints = inlays
|
||||
.map { it.renderer }
|
||||
.mapNotNull { if (it is EditorCustomTextElementRenderer) it else null }
|
||||
.map { it.text }
|
||||
|
||||
trySend(text, hints)
|
||||
}
|
||||
|
||||
private fun trySend(text: String, inlays: List<String>) {
|
||||
val report = InlayReport(text, inlays)
|
||||
writeToFile(createReportLine(recorderId, report))
|
||||
trySendFileInBackground()
|
||||
}
|
||||
|
||||
private fun trySendFileInBackground() {
|
||||
if (!file.exists() || file.length() == 0L) return
|
||||
|
||||
ApplicationManager.getApplication().executeOnPooledThread {
|
||||
val text = file.readText()
|
||||
if (StatsSender.send(text)) {
|
||||
file.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showHint(editor: Editor) {
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
HintManager.getInstance().showInformationHint(editor, "Troubled inline hint was reported")
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeToFile(line: String) {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile()
|
||||
}
|
||||
file.appendText(line)
|
||||
}
|
||||
|
||||
private fun getCurrentLineRange(editor: Editor): TextRange {
|
||||
val offset = editor.caretModel.currentCaret.offset
|
||||
val document = editor.document
|
||||
val line = document.getLineNumber(offset)
|
||||
return TextRange(document.getLineStartOffset(line), document.getLineEndOffset(line))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun isHintsEnabled() = Registry.`is`("editor.inline.parameter.hints")
|
||||
|
||||
private fun Editor.getInlays(range: TextRange): List<Inlay> {
|
||||
return inlayModel.getInlineElementsInRange(range.startOffset, range.endOffset)
|
||||
}
|
||||
|
||||
private class InlayReport(var text: String, var inlays: List<String>)
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.editor;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface EditorCustomTextElementRenderer extends EditorCustomElementRenderer {
|
||||
@NotNull
|
||||
String getText();
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.reporting
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.intellij.openapi.application.PermanentInstallationID
|
||||
import org.apache.http.client.fluent.Request
|
||||
import org.apache.http.entity.ContentType
|
||||
|
||||
|
||||
private class StatsServerInfo(var status: String, var url: String) {
|
||||
fun isServiceAlive() = "ok" == status
|
||||
}
|
||||
|
||||
private object Utils {
|
||||
val gson = Gson()
|
||||
}
|
||||
|
||||
|
||||
object StatsSender {
|
||||
private val infoUrl = "https://www.jetbrains.com/config/features-service-status.json"
|
||||
|
||||
private fun requestServerUrl(): String? {
|
||||
try {
|
||||
val response = Request.Get(infoUrl).execute().returnContent().asString()
|
||||
val info = Utils.gson.fromJson(response, StatsServerInfo::class.java)
|
||||
if (info.isServiceAlive()) return info.url
|
||||
}
|
||||
catch (e: Exception) {
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun send(text: String): Boolean {
|
||||
val url = requestServerUrl() ?: return false
|
||||
try {
|
||||
val response = Request.Post(url).bodyString(text, ContentType.TEXT_HTML).execute()
|
||||
val code = response.handleResponse { it.statusLine.statusCode }
|
||||
if (code >= 200 && code < 300) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
catch (e: Exception) {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun <T> createReportLine(recorderId: String, data: T): String {
|
||||
val json = Utils.gson.toJson(data)
|
||||
val userUid = PermanentInstallationID.get()
|
||||
val stamp = System.currentTimeMillis()
|
||||
return "$stamp\t$recorderId\t$userUid\trandom_session_id\t$json"
|
||||
}
|
||||
@@ -51,6 +51,9 @@
|
||||
<component>
|
||||
<implementation-class>com.intellij.util.xml.impl.JavaDomApplicationComponent</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>com.intellij.reporting.InlineHintReporterRegistration</implementation-class>
|
||||
</component>
|
||||
</application-components>
|
||||
|
||||
<project-components>
|
||||
|
||||
Reference in New Issue
Block a user