mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-04-22 01:15:48 +02:00
Show possible IDs based on the action's shortcuts
Fixes VIM-3499
This commit is contained in:
parent
64f7532510
commit
e07a16863e
@ -222,13 +222,13 @@ Ex commands or via `:map` command mappings:
|
||||
* Execute an action by `{action_id}`. Works from Ex command line.
|
||||
* Please don't use `:action` in mappings. Use `<Action>` instead.
|
||||
|
||||
### Finding action ids:
|
||||
### Finding action IDs:
|
||||
|
||||
* IJ provides `IdeaVim: track action Ids` command to show the id of the executed actions.
|
||||
* IJ provides `IdeaVim: track action IDs` command to show the id of the executed actions.
|
||||
This command can be found in "Search everywhere" (double `shift`).
|
||||
|
||||
<details>
|
||||
<summary><strong>"Track action Ids" Details</strong> (click to see)</summary>
|
||||
<summary><strong>"Track action IDs" Details</strong> (click to see)</summary>
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="assets/readme/track_action_dark.gif">
|
||||
<img src="assets/readme/track_action_light.gif" alt="track action ids"/>
|
||||
|
@ -5,9 +5,9 @@ Using actions from external plugins is the same, as tracking and reusing any IDE
|
||||
1. Install the plugin via Marketplace
|
||||
2. Enable action tracking. You can enable it by one of the following ways:
|
||||
* Execute `:set trackactionids` ex command or just `:set tai`
|
||||
* Open the "Find actions" window by pressing `Ctrl-Shift-A` and search for "Track Action Ids" to find the toggle that enables and disables action tracking
|
||||
* Open the "Find actions" window by pressing `Ctrl-Shift-A` and search for "Track Action IDs" to find the toggle that enables and disables action tracking
|
||||
3. Execute the plugin action the way intended by plugin author "See Edit menu or use ⇧ + ⌥ + U / Shift + Alt + U" or just find the `Toggle Camel Case` action in the "Find actions" window (`Ctrl-Shift-A`). If you action tracking is on, you will see this notification in your right bottom corner:
|
||||
|
||||
<img alt="Notification" src="images/action-id-notification.png"/>
|
||||
4. Copy the action id from the notification to create the following mapping in your .ideavimrc
|
||||
```map <leader>t <Action>(de.netnexus.CamelCasePlugin.ToggleCamelCase)```
|
||||
```map <leader>t <Action>(de.netnexus.CamelCasePlugin.ToggleCamelCase)```
|
||||
|
@ -182,8 +182,8 @@ internal class NotificationService(private val project: Project?) {
|
||||
).notify(project)
|
||||
}
|
||||
|
||||
fun notifyActionId(id: String?) {
|
||||
ActionIdNotifier.notifyActionId(id, project)
|
||||
fun notifyActionId(id: String?, candidates: List<String>? = null) {
|
||||
ActionIdNotifier.notifyActionId(id, project, candidates)
|
||||
}
|
||||
|
||||
fun notifyKeymapIssues(issues: ArrayList<KeyMapIssue>) {
|
||||
@ -259,20 +259,31 @@ internal class NotificationService(private val project: Project?) {
|
||||
|
||||
object ActionIdNotifier {
|
||||
private var notification: Notification? = null
|
||||
private const val NO_ID = "<i>Cannot detect action id</i>"
|
||||
|
||||
fun notifyActionId(id: String?, project: Project?) {
|
||||
fun notifyActionId(id: String?, project: Project?, candidates: List<String>? = null) {
|
||||
notification?.expire()
|
||||
|
||||
val content = if (id != null) "Action id: $id" else NO_ID
|
||||
Notification(IDEAVIM_NOTIFICATION_ID, IDEAVIM_NOTIFICATION_TITLE, content, NotificationType.INFORMATION).let {
|
||||
notification = it
|
||||
it.whenExpired { notification = null }
|
||||
it.setContent(it.content + "<br><br><small>Use ${ActionCenter.getToolwindowName()} to see previous ids</small>")
|
||||
val possibleIDs = candidates?.distinct()?.sorted()
|
||||
val content = when {
|
||||
id != null -> "Action ID: <code>$id</code><br><br>"
|
||||
possibleIDs.isNullOrEmpty() -> "<i>Cannot detect action ID</i><br><br>"
|
||||
possibleIDs.size == 1 -> "Possible action ID: <code>${possibleIDs[0]}</code><br><br>"
|
||||
else -> {
|
||||
buildString {
|
||||
append("<p>Multiple possible action IDs. Candidates include:<ul>")
|
||||
possibleIDs.forEach { append("<li><code>$it</code></li>") }
|
||||
append("</ul></p>")
|
||||
}
|
||||
}
|
||||
} + "<small>See the ${ActionCenter.getToolwindowName()} tool window for previous IDs</small>"
|
||||
|
||||
notification = Notification(IDEAVIM_NOTIFICATION_ID, IDEAVIM_NOTIFICATION_TITLE, content, NotificationType.INFORMATION).also {
|
||||
it.whenExpired { notification = null }
|
||||
it.addAction(StopTracking())
|
||||
|
||||
if (id != null) it.addAction(CopyActionId(id, project))
|
||||
if (id != null || possibleIDs?.size == 1) {
|
||||
it.addAction(CopyActionId(id ?: possibleIDs?.get(0), project))
|
||||
}
|
||||
|
||||
it.notify(project)
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.actionSystem.ex.AnActionListener
|
||||
import com.intellij.openapi.actionSystem.impl.ProxyShortcutSet
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.keymap.KeymapManager
|
||||
import com.intellij.openapi.project.DumbAwareToggleAction
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.maddyhome.idea.vim.KeyHandler
|
||||
@ -58,6 +59,7 @@ internal object IdeaSpecifics {
|
||||
private var editor: Editor? = null
|
||||
private var completionPrevDocumentLength: Int? = null
|
||||
private var completionPrevDocumentOffset: Int? = null
|
||||
|
||||
override fun beforeActionPerformed(action: AnAction, event: AnActionEvent) {
|
||||
if (VimPlugin.isNotEnabled()) return
|
||||
|
||||
@ -70,7 +72,24 @@ internal object IdeaSpecifics {
|
||||
if (!isVimAction && injector.globalIjOptions().trackactionids) {
|
||||
if (action !is NotificationService.ActionIdNotifier.CopyActionId && action !is NotificationService.ActionIdNotifier.StopTracking) {
|
||||
val id: String? = ActionManager.getInstance().getId(action) ?: (action.shortcutSet as? ProxyShortcutSet)?.actionId
|
||||
VimPlugin.getNotifications(event.dataContext.getData(CommonDataKeys.PROJECT)).notifyActionId(id)
|
||||
val candidates = if (id == null) {
|
||||
// Some actions are specific to the component they're registered for, and are copies of a global action,
|
||||
// reusing the action ID and shortcuts (e.g. `NextTab` is different for editor tabs and tool window tabs).
|
||||
// Unfortunately, ActionManager doesn't know about these "local" actions, so can't return the action ID.
|
||||
// However, the new "local" action does copy the shortcuts of the global template action, so we can look up
|
||||
// all actions with matching shortcuts. We might return more action IDs than expected, so this is a list of
|
||||
// candidates, not a definite match of the action being executed, but the list should include our target
|
||||
// action. Note that we might return duplicate IDs because the keymap might have multiple shortcuts mapped
|
||||
// to the same action. The notifier will handle de-duplication and sorting as a presentation detail.
|
||||
action.shortcutSet.shortcuts.flatMap { KeymapManager.getInstance().activeKeymap.getActionIdList(it) }
|
||||
}
|
||||
else {
|
||||
emptyList()
|
||||
}
|
||||
|
||||
// We can still get empty ID and empty candidates. Notably, for the tool window toggle buttons on the new UI.
|
||||
// We could filter out action events with `place == ActionPlaces.TOOLWINDOW_TOOLBAR_BAR`
|
||||
VimPlugin.getNotifications(event.dataContext.getData(CommonDataKeys.PROJECT)).notifyActionId(id, candidates)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,8 +100,8 @@ action.not.found.0=Action not found: {0}
|
||||
|
||||
action.CustomizeModeWidget.text=Mode Widget Settings
|
||||
|
||||
action.VimFindActionIdAction.text=IdeaVim: Track Action Ids
|
||||
action.VimFindActionIdAction.description=Starts tracking ids of executed actions
|
||||
action.VimFindActionIdAction.text=IdeaVim: Track Action IDs
|
||||
action.VimFindActionIdAction.description=Starts tracking IDs of executed actions
|
||||
|
||||
ex.show.all.actions.0.1=--- Actions ---{0}{1}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user