mirror of
https://github.com/chylex/IntelliJ-AceJump.git
synced 2025-09-15 14:32:08 +02:00
Compare commits
30 Commits
d905909e31
...
pr-optimiz
Author | SHA1 | Date | |
---|---|---|---|
04c1519261
|
|||
![]() |
efc81b8fde | ||
![]() |
974c5cf258 | ||
![]() |
ae458094cf | ||
![]() |
db62460d83 | ||
![]() |
09888c2c34 | ||
![]() |
1d1f469663 | ||
![]() |
21df680792 | ||
![]() |
1af49c2e91 | ||
![]() |
ec7a769ae7 | ||
![]() |
d6d162e4cc | ||
![]() |
9d478c5b6e | ||
![]() |
b66868664e | ||
![]() |
c68487c989 | ||
![]() |
ca2b0a8dbe | ||
![]() |
76bc72335b | ||
![]() |
fe4e180aeb | ||
![]() |
932c933969 | ||
![]() |
16f205b11b | ||
d0ead7d87a
|
|||
![]() |
c2e672f869 | ||
![]() |
1256ffc237 | ||
![]() |
29a71bdddc | ||
![]() |
9d2e7f7569 | ||
![]() |
751e6d890b | ||
![]() |
283c1a5644 | ||
![]() |
73a37df7e2 | ||
9921409aff
|
|||
![]() |
3039b5fbb3 | ||
cb3d4559f9
|
16
CHANGES.md
16
CHANGES.md
@@ -2,6 +2,22 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 3.8.19
|
||||
|
||||
- Enable support for 2024.1, fixing ([#457](https://github.com/acejump/AceJump/issues/457))
|
||||
|
||||
## 3.8.18
|
||||
|
||||
- Disable tagging and jumping to folded regions ([#453](https://github.com/acejump/AceJump/issues/453)), thanks to [@chylex](https://github.com/chylex)
|
||||
- Update hint styling and show mode ([#394](https://github.com/acejump/AceJump/issues/394)) when "Show hint with search text" is enabled
|
||||
- Fixes "Char sequence is empty" ([#404](https://github.com/acejump/AceJump/issues/404)) when "Map Unicode to ASCII" is enabled
|
||||
|
||||
## 3.8.17
|
||||
|
||||
- Add buttons to reset colors to default values in Settings, [#411](https://github.com/acejump/AceJump/issues/411), thanks to [@chylex](https://github.com/chylex)
|
||||
- Unbundle conflicting Kotlin Standard Library version, [#449](https://github.com/acejump/AceJump/issues/449), thanks to [@chylex](https://github.com/chylex)
|
||||
- Fix some instances of "Read access not allowed", [#447](https://github.com/acejump/AceJump/issues/447), thanks to [@h0tk3y](https://github.com/h0tk3y)
|
||||
|
||||
## 3.8.16
|
||||
|
||||
- Fix issue with unselectable tags, [#446](https://github.com/acejump/AceJump/issues/446)
|
||||
|
31
README.md
31
README.md
@@ -8,13 +8,6 @@
|
||||
<a href="https://twitter.com/search?q=AceJump&f=live" title="Twitter"><img src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"></a>
|
||||
</p>
|
||||
|
||||
> **Note**: There is currently an outstanding issue with [settings deserialization](https://github.com/acejump/AceJump/issues/445). If the AceJump settings were changed in the past, they can become corrupted and may need to be manually deleted. The location varies depending on the operating system and platform version used. For IntelliJ IDEA, the plugin settings file is located in either `options` or `plugins` in the following directories:
|
||||
> * Mac: `~/Library/Application Support/JetBrains/IntelliJIdea<VERSION>`
|
||||
> * Windows: `%APPDATA%\JetBrains\IntelliJIdea<VERSION>`
|
||||
> * Linux: `~/.local/share/JetBrains/IntelliJIdea<VERSION>`
|
||||
>
|
||||
> If not found, you can locate this file via the command, `find . | grep AceJump.xml` under the `JetBrains` directory. We apologize for any inconvenience this may have caused.
|
||||
|
||||
[AceJump](https://plugins.jetbrains.com/plugin/7086) is a plugin for the [IntelliJ Platform](https://github.com/JetBrains/intellij-community/) that lets you jump to any symbol in the editor with just a few keystrokes. Press the keyboard shortcut for `AceAction` (<kbd>Ctrl</kbd>+<kbd>;</kbd> by default) to activate AceJump. Type any string in the editor, followed by one of the illustrated tags, to jump its position:
|
||||
|
||||

|
||||
@@ -31,8 +24,6 @@ Press the AceJump shortcut, followed by <kbd>→</kbd> to target the last, <kbd>
|
||||
|
||||

|
||||
|
||||
AceJump search is [smart case](http://ideavim.sourceforge.net/vim/usr_27.html#vim.27%2E1) sensitive, however tag selection is *not* case sensitive. Holding down <kbd>Shift</kbd> when typing the last tag character will select all text from the current cursor position to that destination.
|
||||
|
||||
## Tips
|
||||
|
||||
- Press <kbd>Tab</kbd> when searching to jump to the next group of matches in the editor.
|
||||
@@ -41,6 +32,10 @@ AceJump search is [smart case](http://ideavim.sourceforge.net/vim/usr_27.html#vi
|
||||
|
||||
- If no matches can be found on-screen, AceJump will scroll to the next match it can find.
|
||||
|
||||
- Note that search is [smart case](http://ideavim.sourceforge.net/vim/usr_27.html#vim.27%2E1) sensitive, however tag selection is *not* case sensitive.
|
||||
|
||||
- Holding down <kbd>Shift</kbd> when typing the last tag character will select all text from the current cursor position to that destination.
|
||||
|
||||
- Pressing <kbd>Enter</kbd> or <kbd>Shift</kbd>+<kbd>Enter</kbd> during a search will cycle through tagged results on screen.
|
||||
|
||||
- To select a location and continue editing, just press <kbd>Esc</kbd>.
|
||||
@@ -183,16 +178,17 @@ AceJump is inspired by prior work, but adds several improvements, including:
|
||||
The following plugins have a similar UI for navigating text and web browsing:
|
||||
|
||||
| Source Code | Download | Application | Actively Maintained | Language |
|
||||
|:----------------------------------------------------------------------|:-------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------:|:-------------------:|:------------------------------------------------------------------------:|
|
||||
|:----------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:-------------------:|:------------------------------------------------------------------------:|
|
||||
| AceJump | [⬇](https://plugins.jetbrains.com/plugin/7086-acejump) | [IntelliJ Platform](https://jetbrains.com) | :heavy_check_mark: | [Kotlin](http://kotlinlang.org/) |
|
||||
| [IdeaVim-EasyMotion](https://github.com/AlexPl292/IdeaVim-EasyMotion) | [⬇](https://github.com/AlexPl292/IdeaVim-EasyMotion) | [IntelliJ Platform](https://jetbrains.com) | :heavy_check_mark: | [Kotlin](http://kotlinlang.org/) |
|
||||
| [KJump](https://github.com/a690700752/KJump) | [⬇](https://plugins.jetbrains.com/plugin/10149-kjump) | [IntelliJ Platform](https://jetbrains.com) | :heavy_check_mark: | [Kotlin](http://kotlinlang.org/) |
|
||||
| [AceJump-Lite](https://github.com/EeeMt/AceJump-Lite) | [⬇](https://plugins.jetbrains.com/plugin/9803-acejump-lite) | [IntelliJ Platform](https://jetbrains.com) | :x: | [Java](https://www.java.com) |
|
||||
| [emacsIDEAs](https://github.com/whunmr/emacsIDEAs) | [⬇](https://plugins.jetbrains.com/plugin/7163-emacsideas) | [IntelliJ Platform](https://jetbrains.com) | :x: | [Java](https://www.java.com) |
|
||||
| [TraceJump](https://github.com/acejump/tracejump) | [⬇](https://github.com/acejump/tracejump) | Desktop | :heavy_check_mark: | [Kotlin](http://kotlinlang.org/) |
|
||||
| [TraceJump](https://github.com/acejump/tracejump) | [⬇](https://github.com/acejump/tracejump) | Desktop | :x: | [Kotlin](http://kotlinlang.org/) |
|
||||
| [ace-jump-mode](https://github.com/winterTTr/ace-jump-mode) | [⬇](https://melpa.org/#/ace-jump-mode) | [emacs](https://www.gnu.org/software/emacs/) | :x: | [Emacs Lisp](https://www.gnu.org/software/emacs/manual/eintr.html) |
|
||||
| [avy](https://github.com/abo-abo/avy) | [⬇](https://melpa.org/#/avy) | [emacs](https://www.gnu.org/software/emacs/) | :heavy_check_mark: | [Emacs Lisp](https://www.gnu.org/software/emacs/manual/eintr.html) |
|
||||
| [EasyMotion](https://github.com/easymotion/vim-easymotion) | [⬇](https://vimawesome.com/plugin/easymotion) | [Vim](http://www.vim.org/) | :x: | [Vimscript](http://learnvimscriptthehardway.stevelosh.com/) |
|
||||
| [eyeliner.nvim](https://github.com/jinh0/eyeliner.nvim) | [⬇](https://github.com/jinh0/eyeliner.nvim?tab=readme-ov-file#-installation) | [NeoVim](https://neovim.io/) | :heavy_check_mark: | [Lua](https://www.lua.org/) |
|
||||
| [Hop](https://github.com/phaazon/hop.nvim) | [⬇](https://github.com/phaazon/hop.nvim#installation) | [NeoVim](https://neovim.io/) | :heavy_check_mark: | [Lua](https://www.lua.org/) |
|
||||
| [leap.nvim](https://github.com/ggandor/leap.nvim) | [⬇](https://github.com/ggandor/leap.nvim#installation) | [NeoVim](https://neovim.io/) | :heavy_check_mark: | [Fennel](https://fennel-lang.org) |
|
||||
| [lightspeed.nvim](https://github.com/ggandor/lightspeed.nvim) | [⬇](https://github.com/ggandor/lightspeed.nvim#installation) | [NeoVim](https://neovim.io/) | :x: | [Fennel](https://fennel-lang.org) |
|
||||
@@ -206,20 +202,23 @@ The following plugins have a similar UI for navigating text and web browsing:
|
||||
| [CodeAceJumper](https://github.com/lucax88x/CodeAceJumper) | [⬇](https://marketplace.visualstudio.com/items?itemName=lucax88x.codeacejumper) | [Visual Studio Code](https://code.visualstudio.com/) | :x: | [TypeScript](https://www.typescriptlang.org/) |
|
||||
| [AceJump](https://github.com/jsturtevant/ace-jump) | [⬇](https://marketplace.visualstudio.com/items?itemName=jsturtevant.AceJump) | [Visual Studio](https://www.visualstudio.com/) | :x: | [C#](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/) |
|
||||
| [EasyMotion](https://github.com/jaredpar/EasyMotion) | [⬇](https://marketplace.visualstudio.com/items?itemName=JaredParMSFT.EasyMotion) | [Visual Studio](https://www.visualstudio.com/) | :x: | [C#](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/) |
|
||||
| [tmux-fingers](https://github.com/Morantron/tmux-fingers) | [⬇](https://github.com/Morantron/tmux-fingers#using-tmux-plugin-manager) | [tmux](https://github.com/tmux/tmux) | :heavy_check_mark: | [Bash](https://www.gnu.org/software/bash/) |
|
||||
| [tmux-fingers](https://github.com/Morantron/tmux-fingers) | [⬇](https://github.com/Morantron/tmux-fingers#using-tmux-plugin-manager) | [tmux](https://github.com/tmux/tmux) | :heavy_check_mark: | [Crystal](https://crystal-lang.org/) |
|
||||
| [tmux-thumb](https://github.com/Morantron/tmux-fingers) | [⬇](https://github.com/fcsonline/tmux-thumbs#using-tmux-plugin-manager) | [tmux](https://github.com/tmux/tmux) | :heavy_check_mark: | [Rust](https://www.rust-lang.org/) |
|
||||
| [tmux-jump](https://github.com/schasse/tmux-jump) | [⬇](https://github.com/schasse/tmux-jump#installation-via-tpm) | [tmux](https://github.com/tmux/tmux) | :heavy_check_mark: | [Ruby](https://www.ruby-lang.org) |
|
||||
| [tmux-copycat](https://github.com/tmux-plugins/tmux-copycat) | [⬇](https://github.com/tmux-plugins/tmux-copycat?tab=readme-ov-file#installation-with-tmux-plugin-manager-recommended) | [tmux](https://github.com/tmux/tmux) | :x: | [Shell](https://www.shellscript.sh/) |
|
||||
| [cVim](https://github.com/1995eaton/chromium-vim) | [⬇](https://chrome.google.com/webstore/detail/cvim/ihlenndgcmojhcghmfjfneahoeklbjjh) | [Chrome](https://www.google.com/chrome) | :x: | [JavaScript](https://www.javascript.com/) |
|
||||
| [SurfingKeys](https://github.com/brookhong/Surfingkeys) | [⬇](https://chrome.google.com/webstore/detail/surfingkeys/gfbliohnnapiefjpjlpjnehglfpaknnc) | [Chrome](https://www.google.com/chrome) / [Firefox](https://www.mozilla.org/firefox) | :heavy_check_mark: | [JavaScript](https://www.javascript.com/) |
|
||||
| [Vimium](https://github.com/philc/vimium) | [⬇](https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb) | [Chrome](https://www.google.com/chrome) | :heavy_check_mark: | [CoffeeScript](http://coffeescript.org/) |
|
||||
| [SurfingKeys](https://github.com/brookhong/Surfingkeys) | [⬇](https://chrome.google.com/webstore/detail/surfingkeys/gfbliohnnapiefjpjlpjnehglfpaknnc) | [Chrome](https://www.google.com/chrome)/[Firefox](https://www.mozilla.org/firefox)/[Edge](https://microsoftedge.microsoft.com/) | :heavy_check_mark: | [JavaScript](https://www.javascript.com/) |
|
||||
| [Vimium](https://github.com/philc/vimium) | [⬇](https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb) | [Chrome](https://www.google.com/chrome)/[Firefox](https://www.mozilla.org/firefox)/[Edge](https://microsoftedge.microsoft.com/) | :heavy_check_mark: | [JavaScript](https://www.javascript.com/) |
|
||||
| [Vimium-C](https://github.com/gdh1995/vimium-c) | [⬇](https://microsoftedge.microsoft.com/addons/detail/vimium-c-all-by-keyboar/aibcglbfblnogfjhbcmmpobjhnomhcdo) | [Chrome](https://www.google.com/chrome)/[Firefox](https://www.mozilla.org/firefox)/[Edge](https://microsoftedge.microsoft.com/) | :heavy_check_mark: | [TypeScript](https://www.typescriptlang.org/) |
|
||||
| [Vrome](https://github.com/jinzhu/vrome) | [⬇](https://chrome.google.com/webstore/detail/vrome/godjoomfiimiddapohpmfklhgmbfffjj) | [Chrome](https://www.google.com/chrome) | :x: | [CoffeeScript](http://coffeescript.org/) |
|
||||
| [ViChrome](https://github.com/k2nr/ViChrome) | [⬇](https://chrome.google.com/webstore/detail/vichrome/gghkfhpblkcmlkmpcpgaajbbiikbhpdi) | [Chrome](https://www.google.com/chrome) | :x: | [CoffeeScript](http://coffeescript.org/) |
|
||||
| [VimFx](https://github.com/akhodakivskiy/VimFx) | [⬇](https://github.com/akhodakivskiy/VimFx/releases) | [Firefox](https://www.mozilla.org/firefox) | :heavy_check_mark: | [CoffeeScript](http://coffeescript.org/) |
|
||||
| [Vimperator](https://github.com/vimperator/vimperator-labs/) | [⬇](https://github.com/vimperator/vimperator-labs/releases) | [Firefox](https://www.mozilla.org/firefox) | :x: | [JavaScript](https://www.javascript.com/) |
|
||||
| [Pentadactyl](https://github.com/5digits/dactyl) | [⬇](http://bug.5digits.org/pentadactyl/#sect-download) | [Firefox](https://www.mozilla.org/firefox) | :x: | [JavaScript](https://www.typescriptlang.org/) |
|
||||
| [Pentadactyl](https://github.com/5digits/dactyl) | [⬇](http://bug.5digits.org/pentadactyl/#sect-download) | [Firefox](https://www.mozilla.org/firefox) | :x: | [JavaScript](https://www.javascript.com/) |
|
||||
| [Vim Vixen](https://github.com/ueokande/vim-vixen) | [⬇](https://addons.mozilla.org/firefox/addon/vim-vixen/) | [Firefox 57+](https://blog.mozilla.org/addons/2017/09/28/webextensions-in-firefox-57/) | :heavy_check_mark: | [JavaScript](https://www.javascript.com/) |
|
||||
| [Tridactyl](https://github.com/tridactyl/tridactyl) | [⬇](https://addons.mozilla.org/firefox/addon/tridactyl-vim/) | [Firefox 57+](https://blog.mozilla.org/addons/2017/09/28/webextensions-in-firefox-57/) | :heavy_check_mark: | [TypeScript](https://www.typescriptlang.org/) |
|
||||
| [Vimari](https://github.com/guyht/vimari) | [⬇](https://github.com/guyht/vimari/releases) | [Safari](https://www.apple.com/safari/) | :heavy_check_mark: | [JavaScript](https://www.javascript.com/) |
|
||||
| [Vimari](https://github.com/guyht/vimari) | [⬇](https://github.com/guyht/vimari/releases) | [Safari](https://www.apple.com/safari/) | :x: | [JavaScript](https://www.javascript.com/) |
|
||||
| [Jump To Link](https://github.com/mrjackphil/obsidian-jump-to-link) | [⬇](https://obsidian.md/plugins?id=mrj-jump-to-link) | [Obsidian](https://obsidian.md/) | :heavy_check_mark: | [TypeScript](https://www.typescriptlang.org/) |
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
|
@@ -1,26 +1,23 @@
|
||||
import org.jetbrains.changelog.Changelog.OutputType.HTML
|
||||
import org.jetbrains.changelog.date
|
||||
import org.jetbrains.intellij.platform.gradle.TestFrameworkType
|
||||
|
||||
plugins {
|
||||
idea apply true
|
||||
kotlin("jvm") version "1.9.20-Beta"
|
||||
id("org.jetbrains.intellij") version "1.15.0"
|
||||
id("org.jetbrains.changelog") version "2.2.0"
|
||||
id("com.github.ben-manes.versions") version "0.48.0"
|
||||
idea
|
||||
alias(libs.plugins.kotlin) // Kotlin support
|
||||
alias(libs.plugins.intelliJPlatform) // IntelliJ Platform Gradle Plugin
|
||||
alias(libs.plugins.changelog) // Gradle Changelog Plugin
|
||||
alias(libs.plugins.kover) // Gradle Kover Plugin
|
||||
id("com.github.ben-manes.versions") version "0.51.0"
|
||||
}
|
||||
|
||||
tasks {
|
||||
compileKotlin {
|
||||
kotlinOptions.jvmTarget = JavaVersion.VERSION_17.toString()
|
||||
}
|
||||
|
||||
named<Zip>("buildPlugin") {
|
||||
dependsOn("test")
|
||||
archiveFileName = "AceJump.zip"
|
||||
}
|
||||
|
||||
runIde {
|
||||
dependsOn("test")
|
||||
findProperty("luginDev")?.let { args = listOf(projectDir.absolutePath) }
|
||||
}
|
||||
|
||||
@@ -36,10 +33,6 @@ tasks {
|
||||
}
|
||||
}
|
||||
|
||||
runPluginVerifier {
|
||||
ideVersions = listOf("2023.2")
|
||||
}
|
||||
|
||||
// Remove pending: https://youtrack.jetbrains.com/issue/IDEA-278926
|
||||
val test by getting(Test::class) {
|
||||
isScanForTestClasses = false
|
||||
@@ -47,15 +40,16 @@ tasks {
|
||||
include("**/AceTest.class")
|
||||
include("**/ExternalUsageTest.class")
|
||||
include("**/LatencyTest.class")
|
||||
afterTest(
|
||||
KotlinClosure2({ desc: TestDescriptor, result: TestResult ->
|
||||
println("Completed `${desc.displayName}` in ${result.endTime - result.startTime}ms")
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain {
|
||||
run {
|
||||
languageVersion = JavaLanguageVersion.of(17)
|
||||
}
|
||||
}
|
||||
jvmToolchain(17)
|
||||
sourceSets.all {
|
||||
languageSettings.apply {
|
||||
languageVersion = "2.0"
|
||||
@@ -63,7 +57,7 @@ kotlin {
|
||||
}
|
||||
}
|
||||
|
||||
val acejumpVersion = "3.8.16"
|
||||
val acejumpVersion = "3.8.19"
|
||||
|
||||
changelog {
|
||||
version = acejumpVersion
|
||||
@@ -75,18 +69,31 @@ changelog {
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
intellijPlatform.defaultRepositories()
|
||||
// intellijPlatform.localPlatformArtifacts()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// https://github.com/anyascii/anyascii
|
||||
implementation("com.anyascii:anyascii:0.3.2")
|
||||
intellijPlatform{
|
||||
testImplementation(libs.junit)
|
||||
|
||||
bundledPlugins("com.intellij.java")
|
||||
create("IC", "2024.1.4")
|
||||
pluginVerifier()
|
||||
instrumentationTools()
|
||||
testFramework(TestFrameworkType.Platform)
|
||||
}
|
||||
}
|
||||
|
||||
intellij {
|
||||
version = "2023.2.1"
|
||||
pluginName = "AceJump"
|
||||
updateSinceUntilBuild = false
|
||||
plugins = listOf("java")
|
||||
intellijPlatform {
|
||||
pluginConfiguration {
|
||||
version = acejumpVersion
|
||||
name = "AceJump"
|
||||
}
|
||||
|
||||
pluginVerification.ides.recommended()
|
||||
}
|
||||
|
||||
group = "org.acejump"
|
||||
|
@@ -1 +1,4 @@
|
||||
kotlin.stdlib.default.dependency=false
|
||||
kotlin.incremental.useClasspathSnapshot=false
|
||||
|
||||
org.gradle.jvmargs=-Xmx2048m
|
||||
|
18
gradle/libs.versions.toml
Normal file
18
gradle/libs.versions.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[versions]
|
||||
# libraries
|
||||
junit = "4.13.2"
|
||||
|
||||
# plugins
|
||||
changelog = "2.2.1"
|
||||
intelliJPlatform = "2.0.0"
|
||||
kotlin = "2.0.0"
|
||||
kover = "0.8.3"
|
||||
|
||||
[libraries]
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
|
||||
[plugins]
|
||||
changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" }
|
||||
intelliJPlatform = { id = "org.jetbrains.intellij.platform", version.ref = "intelliJPlatform" }
|
||||
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
||||
kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" }
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
@@ -4,6 +4,7 @@ import com.anyascii.AnyAscii
|
||||
import com.intellij.diff.util.DiffUtil.getLineCount
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.editor.*
|
||||
import com.intellij.openapi.util.Computable
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList
|
||||
import org.acejump.config.AceConfig
|
||||
import java.awt.Point
|
||||
@@ -40,7 +41,7 @@ object EditorsCache {
|
||||
}
|
||||
|
||||
fun CharSequence.mapToASCII() =
|
||||
map { AnyAscii.transliterate("$it").first() }.joinToString("")
|
||||
map { AnyAscii.transliterate("$it").firstOrNull() ?: it }.joinToString("")
|
||||
|
||||
/**
|
||||
* Returns true if [this] contains [otherText] at the specified offset.
|
||||
@@ -252,3 +253,9 @@ fun Editor.normalizeOffset(line: Int, offset: Int, allowEnd: Boolean = true) =
|
||||
if (getFileSize(allowEnd) == 0) 0 else
|
||||
max(min(offset, getLineEndOffset(line, allowEnd)), getLineStartOffset(line))
|
||||
|
||||
// https://plugins.jetbrains.com/docs/intellij/general-threading-rules.html#read-access
|
||||
fun <T> read(action: () -> T): T =
|
||||
ApplicationManager.getApplication().runReadAction(Computable { action() })
|
||||
|
||||
fun <T> write(action: () -> T): T =
|
||||
ApplicationManager.getApplication().runWriteAction(Computable { action() })
|
||||
|
@@ -3,6 +3,7 @@ package org.acejump.boundaries
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
|
||||
import org.acejump.read
|
||||
import java.awt.Point
|
||||
|
||||
/**
|
||||
@@ -20,6 +21,11 @@ sealed class EditorOffsetCache {
|
||||
*/
|
||||
abstract fun visibleArea(editor: Editor): Pair<Point, Point>
|
||||
|
||||
/**
|
||||
* Returns whether the offset is in the visible area rectangle.
|
||||
*/
|
||||
abstract fun isVisible(editor: Editor, offset: Int): Boolean
|
||||
|
||||
/**
|
||||
* Returns the editor offset at the provided pixel coordinate.
|
||||
*/
|
||||
@@ -34,12 +40,32 @@ sealed class EditorOffsetCache {
|
||||
|
||||
private class Cache: EditorOffsetCache() {
|
||||
private var visibleArea: Pair<Point, Point>? = null
|
||||
private val pointToOffset = Object2IntOpenHashMap<Point>().apply { defaultReturnValue(-1) }
|
||||
private val lineToVisibleOffsetRange = Int2ObjectOpenHashMap<IntRange>()
|
||||
private val pointToOffset =
|
||||
Object2IntOpenHashMap<Point>().apply { defaultReturnValue(-1) }
|
||||
private val offsetToPoint = Int2ObjectOpenHashMap<Point>()
|
||||
|
||||
override fun visibleArea(editor: Editor): Pair<Point, Point> =
|
||||
visibleArea ?: Uncached.visibleArea(editor).also { visibleArea = it }
|
||||
|
||||
override fun isVisible(editor: Editor, offset: Int): Boolean {
|
||||
val visualLine = editor.offsetToVisualLine(offset, false)
|
||||
|
||||
var visibleRange = lineToVisibleOffsetRange.get(visualLine)
|
||||
if (visibleRange == null) {
|
||||
val (topLeft, bottomRight) = visibleArea(editor)
|
||||
val lineY = editor.visualLineToY(visualLine)
|
||||
|
||||
val firstVisibleOffset = xyToOffset(editor, Point(topLeft.x, lineY))
|
||||
val lastVisibleOffset = xyToOffset(editor, Point(bottomRight.x, lineY))
|
||||
|
||||
visibleRange = firstVisibleOffset..lastVisibleOffset
|
||||
lineToVisibleOffsetRange.put(visualLine, visibleRange)
|
||||
}
|
||||
|
||||
return offset in visibleRange
|
||||
}
|
||||
|
||||
override fun xyToOffset(editor: Editor, pos: Point): Int =
|
||||
pointToOffset.getInt(pos).let { offset ->
|
||||
if (offset != -1) offset
|
||||
@@ -62,8 +88,17 @@ sealed class EditorOffsetCache {
|
||||
)
|
||||
}
|
||||
|
||||
override fun isVisible(editor: Editor, offset: Int): Boolean {
|
||||
val (topLeft, bottomRight) = visibleArea(editor)
|
||||
val pos = offsetToXY(editor, offset)
|
||||
val x = pos.x
|
||||
val y = pos.y
|
||||
|
||||
return x >= topLeft.x && y >= topLeft.y && x <= bottomRight.x && y <= bottomRight.y
|
||||
}
|
||||
|
||||
override fun xyToOffset(editor: Editor, pos: Point): Int =
|
||||
editor.logicalPositionToOffset(editor.xyToLogicalPosition(pos))
|
||||
read { editor.logicalPositionToOffset(editor.xyToLogicalPosition(pos)) }
|
||||
|
||||
override fun offsetToXY(editor: Editor, offset: Int): Point =
|
||||
editor.offsetToXY(offset, true, false)
|
||||
|
@@ -21,22 +21,7 @@ enum class StandardBoundaries : Boundaries {
|
||||
}
|
||||
|
||||
override fun isOffsetInside(editor: Editor, offset: Int, cache: EditorOffsetCache): Boolean {
|
||||
// If we are not using a cache, calling getOffsetRange will cause
|
||||
// additional 1-2 pixel coordinate -> offset lookups, which is a lot
|
||||
// more expensive than one lookup compared against the visible area.
|
||||
|
||||
// However, if we are using a cache, it's likely that the topmost and
|
||||
// bottommost positions are already cached whereas the provided offset
|
||||
// isn't, so we save a lookup for every offset outside the range.
|
||||
|
||||
if (cache !== EditorOffsetCache.Uncached && offset !in getOffsetRange(editor, cache)) return false
|
||||
|
||||
val (topLeft, bottomRight) = cache.visibleArea(editor)
|
||||
val pos = cache.offsetToXY(editor, offset)
|
||||
val x = pos.x
|
||||
val y = pos.y
|
||||
|
||||
return x >= topLeft.x && y >= topLeft.y && x <= bottomRight.x && y <= bottomRight.y
|
||||
return cache.isVisible(editor, offset)
|
||||
}
|
||||
},
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
package org.acejump.config
|
||||
|
||||
import com.intellij.openapi.ui.ComboBox
|
||||
import com.intellij.ui.ColorPanel
|
||||
import com.intellij.ui.components.*
|
||||
import com.intellij.ui.dsl.builder.*
|
||||
import org.acejump.input.*
|
||||
import org.acejump.input.JumpMode
|
||||
import org.acejump.input.KeyLayout
|
||||
import java.awt.*
|
||||
import javax.swing.*
|
||||
import javax.swing.text.JTextComponent
|
||||
@@ -15,6 +15,8 @@ import kotlin.reflect.KProperty
|
||||
*/
|
||||
@Suppress("UsePropertyAccessSyntax")
|
||||
internal class AceSettingsPanel {
|
||||
private val defaults = AceSettings()
|
||||
|
||||
private val tagCharsField = JBTextField()
|
||||
private val keyboardLayoutCombo = ComboBox<KeyLayout>()
|
||||
private val keyboardLayoutArea = JBTextArea().apply { isEditable = false }
|
||||
@@ -23,13 +25,13 @@ internal class AceSettingsPanel {
|
||||
private val cycleModeCombo3 = ComboBox<JumpMode>()
|
||||
private val cycleModeCombo4 = ComboBox<JumpMode>()
|
||||
private val minQueryLengthField = JBTextField()
|
||||
private val jumpModeColorWheel = ColorPanel()
|
||||
private val jumpEndModeColorWheel = ColorPanel()
|
||||
private val targetModeColorWheel = ColorPanel()
|
||||
private val definitionModeColorWheel = ColorPanel()
|
||||
private val textHighlightColorWheel = ColorPanel()
|
||||
private val tagForegroundColorWheel = ColorPanel()
|
||||
private val tagBackgroundColorWheel = ColorPanel()
|
||||
private val jumpModeColorWheel = ResettableColorPicker(defaults.getJumpModeJBC())
|
||||
private val jumpEndModeColorWheel = ResettableColorPicker(defaults.getJumpEndModeJBC())
|
||||
private val targetModeColorWheel = ResettableColorPicker(defaults.getTargetModeJBC())
|
||||
private val definitionModeColorWheel = ResettableColorPicker(defaults.getDefinitionModeJBC())
|
||||
private val textHighlightColorWheel = ResettableColorPicker(defaults.getTextHighlightJBC())
|
||||
private val tagForegroundColorWheel = ResettableColorPicker(defaults.getTagForegroundJBC())
|
||||
private val tagBackgroundColorWheel = ResettableColorPicker(defaults.getTagBackgroundJBC())
|
||||
private val searchWholeFileCheckBox = JBCheckBox()
|
||||
private val mapToASCIICheckBox = JBCheckBox()
|
||||
private val showSearchNotificationCheckBox = JBCheckBox()
|
||||
@@ -133,8 +135,8 @@ internal class AceSettingsPanel {
|
||||
private operator fun JTextComponent.getValue(a: AceSettingsPanel, p: KProperty<*>) = text.lowercase()
|
||||
private operator fun JTextComponent.setValue(a: AceSettingsPanel, p: KProperty<*>, s: String) = setText(s)
|
||||
|
||||
private operator fun ColorPanel.getValue(a: AceSettingsPanel, p: KProperty<*>) = selectedColor
|
||||
private operator fun ColorPanel.setValue(a: AceSettingsPanel, p: KProperty<*>, c: Color?) = setSelectedColor(c)
|
||||
private operator fun ResettableColorPicker.getValue(a: AceSettingsPanel, p: KProperty<*>) = getSelectedColor()
|
||||
private operator fun ResettableColorPicker.setValue(a: AceSettingsPanel, p: KProperty<*>, c: Color?) = setSelectedColor(c)
|
||||
|
||||
private operator fun JCheckBox.getValue(a: AceSettingsPanel, p: KProperty<*>) = isSelected
|
||||
private operator fun JCheckBox.setValue(a: AceSettingsPanel, p: KProperty<*>, selected: Boolean) = setSelected(selected)
|
||||
|
47
src/main/kotlin/org/acejump/config/ResettableColorPicker.kt
Normal file
47
src/main/kotlin/org/acejump/config/ResettableColorPicker.kt
Normal file
@@ -0,0 +1,47 @@
|
||||
package org.acejump.config
|
||||
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.openapi.actionSystem.*
|
||||
import com.intellij.openapi.actionSystem.impl.ActionButton
|
||||
import com.intellij.ui.ColorPanel
|
||||
import com.intellij.ui.JBColor
|
||||
import java.awt.*
|
||||
import javax.swing.*
|
||||
|
||||
internal class ResettableColorPicker(private val defaultColor: JBColor) : JPanel(FlowLayout()) {
|
||||
private val resetAction = object : AnAction({ "Reset to Default" }, AllIcons.General.Reset) {
|
||||
override fun getActionUpdateThread(): ActionUpdateThread {
|
||||
return ActionUpdateThread.EDT
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
e.presentation.isEnabled = colorPanel.selectedColor != defaultColor
|
||||
}
|
||||
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
setSelectedColor(defaultColor)
|
||||
}
|
||||
}
|
||||
|
||||
private val colorPanel = ColorPanel()
|
||||
private val resetButton = ActionButton(resetAction, null, ActionPlaces.UNKNOWN, ActionToolbar.DEFAULT_MINIMUM_BUTTON_SIZE)
|
||||
|
||||
init {
|
||||
add(colorPanel)
|
||||
add(resetButton)
|
||||
setSelectedColor(defaultColor)
|
||||
|
||||
colorPanel.addActionListener {
|
||||
resetButton.update()
|
||||
}
|
||||
}
|
||||
|
||||
fun getSelectedColor(): Color? {
|
||||
return colorPanel.selectedColor
|
||||
}
|
||||
|
||||
fun setSelectedColor(color: Color?) {
|
||||
colorPanel.selectedColor = color
|
||||
resetButton.update()
|
||||
}
|
||||
}
|
@@ -20,7 +20,9 @@ enum class KeyLayout(internal val rows: Array<String>, priority: String) {
|
||||
QGMLWY(arrayOf("1234567890", "qgmlwyfub", "dstnriaeoh", "zxcvjkp"), priority = "naterisodhvkcpjxzlfmuwygbq5849673210"),
|
||||
QGMLWB(arrayOf("1234567890", "qgmlwbyuv", "dstnriaeoh", "zxcfjkp"), priority = "naterisodhfkcpjxzlymuwbgvq5849673210"),
|
||||
NORMAN(arrayOf("1234567890", "qwdfkjurl", "asetgynioh", "zxcvbpm"), priority = "tneigysoahbvpcmxzjkufrdlwq5849673210"),
|
||||
AZERTY(arrayOf("1234567890", "azertyuiop", "qsdfghjklm", "wxcvbn"), priority = "fjghdkslqvncmbxwrutyeizoap5849673210");
|
||||
AZERTY(arrayOf("1234567890", "azertyuiop", "qsdfghjklm", "wxcvbn"), priority = "fjghdkslqvncmbxwrutyeizoap5849673210"),
|
||||
CANARY(arrayOf("1234567890", "wlypbzfou", "crstgmneia", "qjvdkxh"), priority = "tngmseracidxvhkjqpfbzyoluw5849673210"),
|
||||
ENGRAM(arrayOf("1234567890", "byouldwvz", "cieahtsnq", "gxjkrmfp"), priority = "ahetiscnkrjmodulywxfgpbvqz3847295610");
|
||||
|
||||
internal val allChars = rows.joinToString("").toCharArray().apply(CharArray::sort).joinToString("")
|
||||
internal val allPriorities = priority.mapIndexed { index, char -> char to index }.toMap()
|
||||
|
@@ -3,6 +3,7 @@ package org.acejump.search
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList
|
||||
import org.acejump.boundaries.Boundaries
|
||||
import org.acejump.boundaries.EditorOffsetCache
|
||||
import org.acejump.immutableText
|
||||
import org.acejump.isWordPart
|
||||
import org.acejump.matchesAt
|
||||
@@ -12,7 +13,6 @@ import org.acejump.matchesAt
|
||||
* previous results when the user [type]s a character.
|
||||
*/
|
||||
internal class SearchProcessor private constructor(
|
||||
private val editors: List<Editor>,
|
||||
query: SearchQuery,
|
||||
results: MutableMap<Editor, IntArrayList>
|
||||
) {
|
||||
@@ -24,14 +24,15 @@ internal class SearchProcessor private constructor(
|
||||
SearchProcessor(editors, SearchQuery.RegularExpression(pattern), boundaries)
|
||||
}
|
||||
|
||||
private constructor(editors: List<Editor>, query: SearchQuery, boundaries: Boundaries) : this(editors, query, mutableMapOf()) {
|
||||
private constructor(editors: List<Editor>, query: SearchQuery, boundaries: Boundaries) : this(query, mutableMapOf()) {
|
||||
val regex = query.toRegex()
|
||||
|
||||
if (regex != null) {
|
||||
for (editor in editors) {
|
||||
val cache = EditorOffsetCache.new()
|
||||
val offsets = IntArrayList()
|
||||
|
||||
val offsetRange = boundaries.getOffsetRange(editor)
|
||||
val offsetRange = boundaries.getOffsetRange(editor, cache)
|
||||
var result = regex.find(editor.immutableText, offsetRange.first)
|
||||
|
||||
while (result != null) {
|
||||
@@ -43,7 +44,7 @@ internal class SearchProcessor private constructor(
|
||||
if (highlightEnd > offsetRange.last) {
|
||||
break
|
||||
}
|
||||
else if (boundaries.isOffsetInside(editor, index)) {
|
||||
else if (boundaries.isOffsetInside(editor, index, cache)) {
|
||||
offsets.add(index)
|
||||
}
|
||||
|
||||
|
@@ -10,7 +10,7 @@ import org.acejump.immutableText
|
||||
import org.acejump.input.KeyLayoutCache
|
||||
import org.acejump.isWordPart
|
||||
import org.acejump.wordEndPlus
|
||||
import java.util.*
|
||||
import java.util.IdentityHashMap
|
||||
import kotlin.math.max
|
||||
|
||||
/*
|
||||
@@ -89,6 +89,10 @@ internal class Solver private constructor(
|
||||
while (iter.hasNext()) {
|
||||
val site = iter.nextInt()
|
||||
|
||||
if (editor.foldingModel.isOffsetCollapsed(site)) {
|
||||
continue
|
||||
}
|
||||
|
||||
for ((firstLetter, tags) in tagsByFirstLetter.entries) {
|
||||
if (canTagBeginWithChar(editor, site, firstLetter)) {
|
||||
for (tag in tags) {
|
||||
|
@@ -1,5 +1,8 @@
|
||||
package org.acejump.search
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.acejump.getView
|
||||
|
||||
data class Tag(val editor: Editor, val offset: Int)
|
||||
data class Tag(val editor: Editor, val offset: Int) {
|
||||
fun isVisible() = offset in editor.getView() && !editor.foldingModel.isOffsetCollapsed(offset)
|
||||
}
|
||||
|
@@ -155,7 +155,7 @@ internal class Tagger(private val editors: List<Editor>) {
|
||||
tagPortion.isNotEmpty()
|
||||
&& label.startsWith(tagPortion, ignoreCase = true)
|
||||
&& isTagCompatibleWithQuery(label, tag, query)
|
||||
&& tag.offset in tag.editor.getView()
|
||||
&& tag.isVisible()
|
||||
}
|
||||
|
||||
private fun removeResultsWithOverlappingTags(editor: Editor, offsets: IntList) {
|
||||
|
@@ -6,6 +6,7 @@ import com.intellij.openapi.editor.event.CaretEvent
|
||||
import com.intellij.openapi.editor.event.CaretListener
|
||||
import org.acejump.boundaries.EditorOffsetCache
|
||||
import org.acejump.boundaries.StandardBoundaries.VISIBLE_ON_SCREEN
|
||||
import org.acejump.read
|
||||
import java.awt.Graphics
|
||||
import java.awt.Graphics2D
|
||||
import java.awt.Rectangle
|
||||
@@ -53,7 +54,7 @@ internal class TagCanvas(private val editor: Editor): JComponent(), CaretListene
|
||||
}
|
||||
|
||||
override fun paint(g: Graphics) =
|
||||
if (!markers.isNullOrEmpty()) super.paint(g) else Unit
|
||||
read { if (!markers.isNullOrEmpty()) super.paint(g) else Unit }
|
||||
|
||||
override fun paintChildren(g: Graphics) {
|
||||
super.paintChildren(g)
|
||||
@@ -66,6 +67,7 @@ internal class TagCanvas(private val editor: Editor): JComponent(), CaretListene
|
||||
|
||||
val cache = EditorOffsetCache.new()
|
||||
val viewRange = VISIBLE_ON_SCREEN.getOffsetRange(editor, cache)
|
||||
val foldingModel = editor.foldingModel
|
||||
val occupied = mutableListOf<Rectangle>()
|
||||
|
||||
// If there is a tag at the caret location, prioritize its rendering over
|
||||
@@ -81,8 +83,9 @@ internal class TagCanvas(private val editor: Editor): JComponent(), CaretListene
|
||||
val caretMarker = markers.find { it.offsetL == caretOffset || it.offsetR == caretOffset }
|
||||
caretMarker?.paint(g, editor, cache, font, occupied)
|
||||
|
||||
for (marker in markers)
|
||||
if (marker.isOffsetInRange(viewRange) && marker !== caretMarker)
|
||||
for (marker in markers) {
|
||||
if (marker.isOffsetInRange(viewRange) && !foldingModel.isOffsetCollapsed(marker.offsetL) && marker !== caretMarker)
|
||||
marker.paint(g, editor, cache, font, occupied)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ import com.intellij.openapi.editor.colors.EditorFontType
|
||||
import com.intellij.openapi.editor.markup.*
|
||||
import com.intellij.openapi.editor.markup.HighlighterTargetArea.EXACT_RANGE
|
||||
import com.intellij.ui.*
|
||||
import com.intellij.ui.util.preferredHeight
|
||||
import com.intellij.util.DocumentUtil
|
||||
import com.intellij.util.ui.*
|
||||
import it.unimi.dsi.fastutil.ints.IntList
|
||||
@@ -96,20 +97,18 @@ internal class TextHighlighter {
|
||||
val editor = results.keys.first()
|
||||
val component: JComponent = editor.component
|
||||
|
||||
val label1 = NotificationLabel(
|
||||
" " +
|
||||
CodeInsightBundle.message("incremental.search.tooltip.prefix")
|
||||
).apply { font = UIUtil.getLabelFont().deriveFont(Font.BOLD) }
|
||||
val label1 = NotificationLabel(" $jumpMode Mode:")
|
||||
.apply { font = UIUtil.getLabelFont().deriveFont(Font.BOLD) }
|
||||
|
||||
val queryText = " " +
|
||||
if (query is SearchQuery.RegularExpression) query.toRegex().toString()
|
||||
else query.rawText[0] + query.rawText.drop(1).lowercase()
|
||||
(if (query is SearchQuery.RegularExpression) query.toRegex().toString()
|
||||
else query.rawText[0] + query.rawText.drop(1).lowercase()) + " "
|
||||
val label2 = NotificationLabel(queryText)
|
||||
|
||||
val label3 = NotificationLabel(
|
||||
"Found ${results.values.flatMap { it.asIterable() }.size}" +
|
||||
" results in ${results.keys.size}" +
|
||||
" editor" + if (1 != results.keys.size) "s" else "."
|
||||
" editor" + if (1 != results.keys.size) "s" else ". "
|
||||
)
|
||||
|
||||
val panel = JPanel(BorderLayout()).apply {
|
||||
@@ -120,10 +119,7 @@ internal class TextHighlighter {
|
||||
if (jumpMode == JumpMode.DISABLED) JBColor.BLACK else jumpMode.caretColor
|
||||
)
|
||||
|
||||
preferredSize = Dimension(
|
||||
editor.contentComponent.width +
|
||||
label1.preferredSize.width, preferredSize.height
|
||||
)
|
||||
preferredHeight = label1.preferredSize.height + 10
|
||||
}
|
||||
|
||||
val hint = LightweightHint(panel)
|
||||
|
Reference in New Issue
Block a user