1
0
mirror of https://github.com/chylex/IntelliJ-AceJump.git synced 2025-09-15 22:32:11 +02:00

30 Commits

Author SHA1 Message Date
04c1519261 Optimize screen visibility checks during search
When 'Search whole file' is disabled, search results are tested for visibility on the screen. There is already an optimization that only checks results on visible lines, but the number of offset-to-XY conversions still scales linearly with the number of results, which can be very large in files with long lines.

A simple observation is that every line has a first and last offset that is visible on the screen (which may be different for each line due to proportional fonts).

This commit caches the visible offset range for every line involved in one search query, so testing visibility of a search result becomes a check if its offset is inside its line's visible offset range. Finding the visible offset range requires two XY-to-offset conversions per line, so the total number of conversions is bounded by the number of lines that can fit on the screen.

The worst case for this optimization is when every line has exactly one search result; before, this would lead to one offset-to-XY conversion per line, whereas now it leads to two XY-to-offset conversions per line. However, the maximum number of conversions is twice the number of visible lines, which will generally be very small.
2024-09-05 01:48:30 +02:00
breandan
efc81b8fde moved to gradle/libs.versions.toml 2024-08-02 15:47:33 -04:00
breandan
974c5cf258 Merge remote-tracking branch 'origin/master' 2024-08-02 15:11:58 -04:00
breandan
ae458094cf update to intellij gradle plugin v2 2024-08-02 15:11:49 -04:00
breandan
db62460d83 Merge pull request #460 from skyrylyuk/AceJump-139
#139 Improve test coverage - Add plugin for calculation Code Coverage
2024-08-02 15:07:08 -04:00
breandan
09888c2c34 Merge pull request #462 from KaelWD/patch-1
Add ENGRAM key layout
2024-08-02 14:55:30 -04:00
Kael
1d1f469663 Add ENGRAM key layout 2024-07-08 18:41:53 +10:00
Serhiy Kyrylyuk
21df680792 #139 Improve test coverage - Add plugin for calculation Code Coverage 2024-06-27 12:39:20 +03:00
breandan
1af49c2e91 Merge pull request #458 from Zilainfo/add-canary-key-layout
Add CANARY keyboard layout
2024-05-30 16:06:27 -04:00
kstas
ec7a769ae7 Add CANARY keyboard layout 2024-05-29 20:47:38 +03:00
breandan
d6d162e4cc Merge remote-tracking branch 'origin/master' 2024-04-29 10:10:20 -04:00
breandan
9d478c5b6e benchmark test latency 2024-04-29 10:10:12 -04:00
breandan
b66868664e remove obsolete warning 2024-04-23 21:02:02 -04:00
breandan
c68487c989 build against platform 2024.1, #457 2024-04-06 16:43:35 -04:00
breandan
ca2b0a8dbe fix language 2024-02-27 10:21:51 -05:00
breandan
76bc72335b update versions 2024-02-26 23:11:57 -05:00
breandan
fe4e180aeb add Jinho's project 2024-02-26 19:56:10 -05:00
breandan
932c933969 update versions and change notes, release 3.8.18 2024-01-01 17:46:38 -05:00
breandan
16f205b11b Merge pull request #455 from chylex/pr-folds
Do not assign tags inside folded regions
2024-01-01 17:29:17 -05:00
d0ead7d87a Do not assign tags inside folded regions
Closes #453
2024-01-01 11:39:35 +01:00
breandan
c2e672f869 add tmux-copycat 2023-12-19 18:25:04 -05:00
breandan
1256ffc237 update comparison chart 2023-12-19 18:20:00 -05:00
breandan
29a71bdddc fixes #404 2023-12-19 17:22:16 -05:00
breandan
9d2e7f7569 adjust hint styling and fix #394 2023-12-19 07:57:25 -05:00
breandan
751e6d890b fixes #452 2023-12-12 08:41:59 -05:00
breandan
283c1a5644 update change notes and release 3.8.17 2023-11-04 02:30:56 -04:00
breandan
73a37df7e2 add helpers for read and write actions 2023-10-28 18:10:14 -04:00
9921409aff Add buttons to reset colors to default values in Settings
Closes #411
2023-10-28 13:58:06 +02:00
breandan
3039b5fbb3 Merge pull request #450 from chylex/pr/kotlin-stdlib
Do not bundle kotlin stdlib
2023-10-28 00:21:29 -04:00
cb3d4559f9 Do not bundle kotlin stdlib
Fixes #449
2023-10-27 20:42:45 +02:00
18 changed files with 253 additions and 125 deletions

View File

@@ -2,6 +2,22 @@
## Unreleased ## 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 ## 3.8.16
- Fix issue with unselectable tags, [#446](https://github.com/acejump/AceJump/issues/446) - Fix issue with unselectable tags, [#446](https://github.com/acejump/AceJump/issues/446)

View File

@@ -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> <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> </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: [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:
![](https://cloud.githubusercontent.com/assets/175716/20177444/124fb534-a74d-11e6-8912-1d220ae27091.png) ![](https://cloud.githubusercontent.com/assets/175716/20177444/124fb534-a74d-11e6-8912-1d220ae27091.png)
@@ -31,8 +24,6 @@ Press the AceJump shortcut, followed by <kbd>→</kbd> to target the last, <kbd>
![](https://cloud.githubusercontent.com/assets/175716/20177472/4f0ba956-a74d-11e6-97ba-b296eacdd396.png) ![](https://cloud.githubusercontent.com/assets/175716/20177472/4f0ba956-a74d-11e6-97ba-b296eacdd396.png)
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 ## Tips
- Press <kbd>Tab</kbd> when searching to jump to the next group of matches in the editor. - 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. - 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. - 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>. - To select a location and continue editing, just press <kbd>Esc</kbd>.
@@ -182,44 +177,48 @@ AceJump is inspired by prior work, but adds several improvements, including:
The following plugins have a similar UI for navigating text and web browsing: The following plugins have a similar UI for navigating text and web browsing:
| Source Code | Download | Application | Actively Maintained | Language | | 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/) | | 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/) | | [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/) | | [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) | | [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) | | [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) | | [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) | | [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/) | | [EasyMotion](https://github.com/easymotion/vim-easymotion) | [](https://vimawesome.com/plugin/easymotion) | [Vim](http://www.vim.org/) | :x: | [Vimscript](http://learnvimscriptthehardway.stevelosh.com/) |
| [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/) | | [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/) |
| [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) | | [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/) |
| [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) | | [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) |
| [Sublime EasyMotion](https://github.com/tednaleid/sublime-EasyMotion) | [](https://packagecontrol.io/packages/EasyMotion) | [Sublime](https://www.sublimetext.com/) | :x: | [Python](https://www.python.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) |
| [AceJump](https://github.com/ice9js/ace-jump-sublime) | [](https://packagecontrol.io/packages/AceJump) | [Sublime](https://www.sublimetext.com/) | :x: | [Python](https://www.python.org/) | | [Sublime EasyMotion](https://github.com/tednaleid/sublime-EasyMotion) | [](https://packagecontrol.io/packages/EasyMotion) | [Sublime](https://www.sublimetext.com/) | :x: | [Python](https://www.python.org/) |
| [Jumpy](https://github.com/DavidLGoldberg/jumpy) | [](https://atom.io/packages/jumpy) | [Atom](https://atom.io/) | :heavy_check_mark: | [TypeScript](https://www.typescriptlang.org/) | | [AceJump](https://github.com/ice9js/ace-jump-sublime) | [](https://packagecontrol.io/packages/AceJump) | [Sublime](https://www.sublimetext.com/) | :x: | [Python](https://www.python.org/) |
| [Jumpy2](https://github.com/DavidLGoldberg/jumpy2) | [](https://marketplace.visualstudio.com/items?itemName=DavidLGoldberg.jumpy2) | [Visual Studio Code](https://code.visualstudio.com/) | :heavy_check_mark: | [TypeScript](https://www.typescriptlang.org/) | | [Jumpy](https://github.com/DavidLGoldberg/jumpy) | [](https://atom.io/packages/jumpy) | [Atom](https://atom.io/) | :heavy_check_mark: | [TypeScript](https://www.typescriptlang.org/) |
| [Find-Jump](https://github.com/msafi/xvsc/tree/master/findJump) | [](https://marketplace.visualstudio.com/items?itemName=mksafi.find-jump) | [Visual Studio Code](https://code.visualstudio.com/) | :x: | [TypeScript](https://www.typescriptlang.org/) | | [Jumpy2](https://github.com/DavidLGoldberg/jumpy2) | [](https://marketplace.visualstudio.com/items?itemName=DavidLGoldberg.jumpy2) | [Visual Studio Code](https://code.visualstudio.com/) | :heavy_check_mark: | [TypeScript](https://www.typescriptlang.org/) |
| [MetaGo](https://github.com/metaseed/metaGo) | [](https://marketplace.visualstudio.com/items?itemName=metaseed.metago) | [Visual Studio Code](https://code.visualstudio.com/) | :heavy_check_mark: | [TypeScript](https://www.typescriptlang.org/) | | [Find-Jump](https://github.com/msafi/xvsc/tree/master/findJump) | [](https://marketplace.visualstudio.com/items?itemName=mksafi.find-jump) | [Visual Studio Code](https://code.visualstudio.com/) | :x: | [TypeScript](https://www.typescriptlang.org/) |
| [VSCodeVim](https://github.com/VSCodeVim/Vim) | [](https://marketplace.visualstudio.com/items?itemName=vscodevim.vim) | [Visual Studio Code](https://code.visualstudio.com/) | :heavy_check_mark: | [TypeScript](https://www.typescriptlang.org/) | | [MetaGo](https://github.com/metaseed/metaGo) | [](https://marketplace.visualstudio.com/items?itemName=metaseed.metago) | [Visual Studio Code](https://code.visualstudio.com/) | :heavy_check_mark: | [TypeScript](https://www.typescriptlang.org/) |
| [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/) | | [VSCodeVim](https://github.com/VSCodeVim/Vim) | [](https://marketplace.visualstudio.com/items?itemName=vscodevim.vim) | [Visual Studio Code](https://code.visualstudio.com/) | :heavy_check_mark: | [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/) | | [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/) |
| [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/) | | [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/) |
| [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/) | | [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-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-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-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-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/) |
| [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/) | | [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) |
| [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/) | | [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/) |
| [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/) | | [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/) |
| [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/) | | [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/) |
| [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/) | | [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/) |
| [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/) | | [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/) |
| [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/) | | [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/) |
| [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/) | | [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/) |
| [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/) | | [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/) |
| [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/) | | [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/) |
| [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/) | | [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/) | :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 ## Acknowledgements

View File

@@ -1,26 +1,23 @@
import org.jetbrains.changelog.Changelog.OutputType.HTML import org.jetbrains.changelog.Changelog.OutputType.HTML
import org.jetbrains.changelog.date import org.jetbrains.changelog.date
import org.jetbrains.intellij.platform.gradle.TestFrameworkType
plugins { plugins {
idea apply true idea
kotlin("jvm") version "1.9.20-Beta" alias(libs.plugins.kotlin) // Kotlin support
id("org.jetbrains.intellij") version "1.15.0" alias(libs.plugins.intelliJPlatform) // IntelliJ Platform Gradle Plugin
id("org.jetbrains.changelog") version "2.2.0" alias(libs.plugins.changelog) // Gradle Changelog Plugin
id("com.github.ben-manes.versions") version "0.48.0" alias(libs.plugins.kover) // Gradle Kover Plugin
id("com.github.ben-manes.versions") version "0.51.0"
} }
tasks { tasks {
compileKotlin {
kotlinOptions.jvmTarget = JavaVersion.VERSION_17.toString()
}
named<Zip>("buildPlugin") { named<Zip>("buildPlugin") {
dependsOn("test") dependsOn("test")
archiveFileName = "AceJump.zip" archiveFileName = "AceJump.zip"
} }
runIde { runIde {
dependsOn("test")
findProperty("luginDev")?.let { args = listOf(projectDir.absolutePath) } 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 // Remove pending: https://youtrack.jetbrains.com/issue/IDEA-278926
val test by getting(Test::class) { val test by getting(Test::class) {
isScanForTestClasses = false isScanForTestClasses = false
@@ -47,15 +40,16 @@ tasks {
include("**/AceTest.class") include("**/AceTest.class")
include("**/ExternalUsageTest.class") include("**/ExternalUsageTest.class")
include("**/LatencyTest.class") include("**/LatencyTest.class")
afterTest(
KotlinClosure2({ desc: TestDescriptor, result: TestResult ->
println("Completed `${desc.displayName}` in ${result.endTime - result.startTime}ms")
})
)
} }
} }
kotlin { kotlin {
jvmToolchain { jvmToolchain(17)
run {
languageVersion = JavaLanguageVersion.of(17)
}
}
sourceSets.all { sourceSets.all {
languageSettings.apply { languageSettings.apply {
languageVersion = "2.0" languageVersion = "2.0"
@@ -63,7 +57,7 @@ kotlin {
} }
} }
val acejumpVersion = "3.8.16" val acejumpVersion = "3.8.19"
changelog { changelog {
version = acejumpVersion version = acejumpVersion
@@ -75,18 +69,31 @@ changelog {
repositories { repositories {
mavenCentral() mavenCentral()
intellijPlatform.defaultRepositories()
// intellijPlatform.localPlatformArtifacts()
} }
dependencies { dependencies {
// https://github.com/anyascii/anyascii // https://github.com/anyascii/anyascii
implementation("com.anyascii:anyascii:0.3.2") 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 { intellijPlatform {
version = "2023.2.1" pluginConfiguration {
pluginName = "AceJump" version = acejumpVersion
updateSinceUntilBuild = false name = "AceJump"
plugins = listOf("java") }
pluginVerification.ides.recommended()
} }
group = "org.acejump" group = "org.acejump"

View File

@@ -1 +1,4 @@
kotlin.stdlib.default.dependency=false
kotlin.incremental.useClasspathSnapshot=false
org.gradle.jvmargs=-Xmx2048m org.gradle.jvmargs=-Xmx2048m

18
gradle/libs.versions.toml Normal file
View 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" }

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists 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 zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -4,6 +4,7 @@ import com.anyascii.AnyAscii
import com.intellij.diff.util.DiffUtil.getLineCount import com.intellij.diff.util.DiffUtil.getLineCount
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.* import com.intellij.openapi.editor.*
import com.intellij.openapi.util.Computable
import it.unimi.dsi.fastutil.ints.IntArrayList import it.unimi.dsi.fastutil.ints.IntArrayList
import org.acejump.config.AceConfig import org.acejump.config.AceConfig
import java.awt.Point import java.awt.Point
@@ -40,7 +41,7 @@ object EditorsCache {
} }
fun CharSequence.mapToASCII() = 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. * 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 if (getFileSize(allowEnd) == 0) 0 else
max(min(offset, getLineEndOffset(line, allowEnd)), getLineStartOffset(line)) 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() })

View File

@@ -3,6 +3,7 @@ package org.acejump.boundaries
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
import org.acejump.read
import java.awt.Point import java.awt.Point
/** /**
@@ -20,6 +21,11 @@ sealed class EditorOffsetCache {
*/ */
abstract fun visibleArea(editor: Editor): Pair<Point, Point> 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. * Returns the editor offset at the provided pixel coordinate.
*/ */
@@ -34,12 +40,32 @@ sealed class EditorOffsetCache {
private class Cache: EditorOffsetCache() { private class Cache: EditorOffsetCache() {
private var visibleArea: Pair<Point, Point>? = null 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>() private val offsetToPoint = Int2ObjectOpenHashMap<Point>()
override fun visibleArea(editor: Editor): Pair<Point, Point> = override fun visibleArea(editor: Editor): Pair<Point, Point> =
visibleArea ?: Uncached.visibleArea(editor).also { visibleArea = it } 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 = override fun xyToOffset(editor: Editor, pos: Point): Int =
pointToOffset.getInt(pos).let { offset -> pointToOffset.getInt(pos).let { offset ->
if (offset != -1) 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 = 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 = override fun offsetToXY(editor: Editor, offset: Int): Point =
editor.offsetToXY(offset, true, false) editor.offsetToXY(offset, true, false)

View File

@@ -21,22 +21,7 @@ enum class StandardBoundaries : Boundaries {
} }
override fun isOffsetInside(editor: Editor, offset: Int, cache: EditorOffsetCache): Boolean { override fun isOffsetInside(editor: Editor, offset: Int, cache: EditorOffsetCache): Boolean {
// If we are not using a cache, calling getOffsetRange will cause return cache.isVisible(editor, offset)
// 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
} }
}, },

View File

@@ -1,10 +1,10 @@
package org.acejump.config package org.acejump.config
import com.intellij.openapi.ui.ComboBox import com.intellij.openapi.ui.ComboBox
import com.intellij.ui.ColorPanel
import com.intellij.ui.components.* import com.intellij.ui.components.*
import com.intellij.ui.dsl.builder.* import com.intellij.ui.dsl.builder.*
import org.acejump.input.* import org.acejump.input.JumpMode
import org.acejump.input.KeyLayout
import java.awt.* import java.awt.*
import javax.swing.* import javax.swing.*
import javax.swing.text.JTextComponent import javax.swing.text.JTextComponent
@@ -15,6 +15,8 @@ import kotlin.reflect.KProperty
*/ */
@Suppress("UsePropertyAccessSyntax") @Suppress("UsePropertyAccessSyntax")
internal class AceSettingsPanel { internal class AceSettingsPanel {
private val defaults = AceSettings()
private val tagCharsField = JBTextField() private val tagCharsField = JBTextField()
private val keyboardLayoutCombo = ComboBox<KeyLayout>() private val keyboardLayoutCombo = ComboBox<KeyLayout>()
private val keyboardLayoutArea = JBTextArea().apply { isEditable = false } private val keyboardLayoutArea = JBTextArea().apply { isEditable = false }
@@ -23,13 +25,13 @@ internal class AceSettingsPanel {
private val cycleModeCombo3 = ComboBox<JumpMode>() private val cycleModeCombo3 = ComboBox<JumpMode>()
private val cycleModeCombo4 = ComboBox<JumpMode>() private val cycleModeCombo4 = ComboBox<JumpMode>()
private val minQueryLengthField = JBTextField() private val minQueryLengthField = JBTextField()
private val jumpModeColorWheel = ColorPanel() private val jumpModeColorWheel = ResettableColorPicker(defaults.getJumpModeJBC())
private val jumpEndModeColorWheel = ColorPanel() private val jumpEndModeColorWheel = ResettableColorPicker(defaults.getJumpEndModeJBC())
private val targetModeColorWheel = ColorPanel() private val targetModeColorWheel = ResettableColorPicker(defaults.getTargetModeJBC())
private val definitionModeColorWheel = ColorPanel() private val definitionModeColorWheel = ResettableColorPicker(defaults.getDefinitionModeJBC())
private val textHighlightColorWheel = ColorPanel() private val textHighlightColorWheel = ResettableColorPicker(defaults.getTextHighlightJBC())
private val tagForegroundColorWheel = ColorPanel() private val tagForegroundColorWheel = ResettableColorPicker(defaults.getTagForegroundJBC())
private val tagBackgroundColorWheel = ColorPanel() private val tagBackgroundColorWheel = ResettableColorPicker(defaults.getTagBackgroundJBC())
private val searchWholeFileCheckBox = JBCheckBox() private val searchWholeFileCheckBox = JBCheckBox()
private val mapToASCIICheckBox = JBCheckBox() private val mapToASCIICheckBox = JBCheckBox()
private val showSearchNotificationCheckBox = 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.getValue(a: AceSettingsPanel, p: KProperty<*>) = text.lowercase()
private operator fun JTextComponent.setValue(a: AceSettingsPanel, p: KProperty<*>, s: String) = setText(s) 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 ResettableColorPicker.getValue(a: AceSettingsPanel, p: KProperty<*>) = getSelectedColor()
private operator fun ColorPanel.setValue(a: AceSettingsPanel, p: KProperty<*>, c: Color?) = setSelectedColor(c) 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.getValue(a: AceSettingsPanel, p: KProperty<*>) = isSelected
private operator fun JCheckBox.setValue(a: AceSettingsPanel, p: KProperty<*>, selected: Boolean) = setSelected(selected) private operator fun JCheckBox.setValue(a: AceSettingsPanel, p: KProperty<*>, selected: Boolean) = setSelected(selected)

View 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()
}
}

View File

@@ -20,7 +20,9 @@ enum class KeyLayout(internal val rows: Array<String>, priority: String) {
QGMLWY(arrayOf("1234567890", "qgmlwyfub", "dstnriaeoh", "zxcvjkp"), priority = "naterisodhvkcpjxzlfmuwygbq5849673210"), QGMLWY(arrayOf("1234567890", "qgmlwyfub", "dstnriaeoh", "zxcvjkp"), priority = "naterisodhvkcpjxzlfmuwygbq5849673210"),
QGMLWB(arrayOf("1234567890", "qgmlwbyuv", "dstnriaeoh", "zxcfjkp"), priority = "naterisodhfkcpjxzlymuwbgvq5849673210"), QGMLWB(arrayOf("1234567890", "qgmlwbyuv", "dstnriaeoh", "zxcfjkp"), priority = "naterisodhfkcpjxzlymuwbgvq5849673210"),
NORMAN(arrayOf("1234567890", "qwdfkjurl", "asetgynioh", "zxcvbpm"), priority = "tneigysoahbvpcmxzjkufrdlwq5849673210"), 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 allChars = rows.joinToString("").toCharArray().apply(CharArray::sort).joinToString("")
internal val allPriorities = priority.mapIndexed { index, char -> char to index }.toMap() internal val allPriorities = priority.mapIndexed { index, char -> char to index }.toMap()

View File

@@ -3,6 +3,7 @@ package org.acejump.search
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import it.unimi.dsi.fastutil.ints.IntArrayList import it.unimi.dsi.fastutil.ints.IntArrayList
import org.acejump.boundaries.Boundaries import org.acejump.boundaries.Boundaries
import org.acejump.boundaries.EditorOffsetCache
import org.acejump.immutableText import org.acejump.immutableText
import org.acejump.isWordPart import org.acejump.isWordPart
import org.acejump.matchesAt import org.acejump.matchesAt
@@ -12,7 +13,6 @@ import org.acejump.matchesAt
* previous results when the user [type]s a character. * previous results when the user [type]s a character.
*/ */
internal class SearchProcessor private constructor( internal class SearchProcessor private constructor(
private val editors: List<Editor>,
query: SearchQuery, query: SearchQuery,
results: MutableMap<Editor, IntArrayList> results: MutableMap<Editor, IntArrayList>
) { ) {
@@ -24,14 +24,15 @@ internal class SearchProcessor private constructor(
SearchProcessor(editors, SearchQuery.RegularExpression(pattern), boundaries) 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() val regex = query.toRegex()
if (regex != null) { if (regex != null) {
for (editor in editors) { for (editor in editors) {
val cache = EditorOffsetCache.new()
val offsets = IntArrayList() val offsets = IntArrayList()
val offsetRange = boundaries.getOffsetRange(editor) val offsetRange = boundaries.getOffsetRange(editor, cache)
var result = regex.find(editor.immutableText, offsetRange.first) var result = regex.find(editor.immutableText, offsetRange.first)
while (result != null) { while (result != null) {
@@ -43,7 +44,7 @@ internal class SearchProcessor private constructor(
if (highlightEnd > offsetRange.last) { if (highlightEnd > offsetRange.last) {
break break
} }
else if (boundaries.isOffsetInside(editor, index)) { else if (boundaries.isOffsetInside(editor, index, cache)) {
offsets.add(index) offsets.add(index)
} }

View File

@@ -10,7 +10,7 @@ import org.acejump.immutableText
import org.acejump.input.KeyLayoutCache import org.acejump.input.KeyLayoutCache
import org.acejump.isWordPart import org.acejump.isWordPart
import org.acejump.wordEndPlus import org.acejump.wordEndPlus
import java.util.* import java.util.IdentityHashMap
import kotlin.math.max import kotlin.math.max
/* /*
@@ -89,6 +89,10 @@ internal class Solver private constructor(
while (iter.hasNext()) { while (iter.hasNext()) {
val site = iter.nextInt() val site = iter.nextInt()
if (editor.foldingModel.isOffsetCollapsed(site)) {
continue
}
for ((firstLetter, tags) in tagsByFirstLetter.entries) { for ((firstLetter, tags) in tagsByFirstLetter.entries) {
if (canTagBeginWithChar(editor, site, firstLetter)) { if (canTagBeginWithChar(editor, site, firstLetter)) {
for (tag in tags) { for (tag in tags) {

View File

@@ -1,5 +1,8 @@
package org.acejump.search package org.acejump.search
import com.intellij.openapi.editor.Editor 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)
}

View File

@@ -155,7 +155,7 @@ internal class Tagger(private val editors: List<Editor>) {
tagPortion.isNotEmpty() tagPortion.isNotEmpty()
&& label.startsWith(tagPortion, ignoreCase = true) && label.startsWith(tagPortion, ignoreCase = true)
&& isTagCompatibleWithQuery(label, tag, query) && isTagCompatibleWithQuery(label, tag, query)
&& tag.offset in tag.editor.getView() && tag.isVisible()
} }
private fun removeResultsWithOverlappingTags(editor: Editor, offsets: IntList) { private fun removeResultsWithOverlappingTags(editor: Editor, offsets: IntList) {

View File

@@ -6,6 +6,7 @@ import com.intellij.openapi.editor.event.CaretEvent
import com.intellij.openapi.editor.event.CaretListener import com.intellij.openapi.editor.event.CaretListener
import org.acejump.boundaries.EditorOffsetCache import org.acejump.boundaries.EditorOffsetCache
import org.acejump.boundaries.StandardBoundaries.VISIBLE_ON_SCREEN import org.acejump.boundaries.StandardBoundaries.VISIBLE_ON_SCREEN
import org.acejump.read
import java.awt.Graphics import java.awt.Graphics
import java.awt.Graphics2D import java.awt.Graphics2D
import java.awt.Rectangle import java.awt.Rectangle
@@ -53,7 +54,7 @@ internal class TagCanvas(private val editor: Editor): JComponent(), CaretListene
} }
override fun paint(g: Graphics) = 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) { override fun paintChildren(g: Graphics) {
super.paintChildren(g) super.paintChildren(g)
@@ -66,6 +67,7 @@ internal class TagCanvas(private val editor: Editor): JComponent(), CaretListene
val cache = EditorOffsetCache.new() val cache = EditorOffsetCache.new()
val viewRange = VISIBLE_ON_SCREEN.getOffsetRange(editor, cache) val viewRange = VISIBLE_ON_SCREEN.getOffsetRange(editor, cache)
val foldingModel = editor.foldingModel
val occupied = mutableListOf<Rectangle>() val occupied = mutableListOf<Rectangle>()
// If there is a tag at the caret location, prioritize its rendering over // 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 } val caretMarker = markers.find { it.offsetL == caretOffset || it.offsetR == caretOffset }
caretMarker?.paint(g, editor, cache, font, occupied) caretMarker?.paint(g, editor, cache, font, occupied)
for (marker in markers) for (marker in markers) {
if (marker.isOffsetInRange(viewRange) && marker !== caretMarker) if (marker.isOffsetInRange(viewRange) && !foldingModel.isOffsetCollapsed(marker.offsetL) && marker !== caretMarker)
marker.paint(g, editor, cache, font, occupied) marker.paint(g, editor, cache, font, occupied)
}
} }
} }

View File

@@ -9,6 +9,7 @@ import com.intellij.openapi.editor.colors.EditorFontType
import com.intellij.openapi.editor.markup.* import com.intellij.openapi.editor.markup.*
import com.intellij.openapi.editor.markup.HighlighterTargetArea.EXACT_RANGE import com.intellij.openapi.editor.markup.HighlighterTargetArea.EXACT_RANGE
import com.intellij.ui.* import com.intellij.ui.*
import com.intellij.ui.util.preferredHeight
import com.intellij.util.DocumentUtil import com.intellij.util.DocumentUtil
import com.intellij.util.ui.* import com.intellij.util.ui.*
import it.unimi.dsi.fastutil.ints.IntList import it.unimi.dsi.fastutil.ints.IntList
@@ -96,20 +97,18 @@ internal class TextHighlighter {
val editor = results.keys.first() val editor = results.keys.first()
val component: JComponent = editor.component val component: JComponent = editor.component
val label1 = NotificationLabel( val label1 = NotificationLabel(" $jumpMode Mode:")
" " + .apply { font = UIUtil.getLabelFont().deriveFont(Font.BOLD) }
CodeInsightBundle.message("incremental.search.tooltip.prefix")
).apply { font = UIUtil.getLabelFont().deriveFont(Font.BOLD) }
val queryText = " " + val queryText = " " +
if (query is SearchQuery.RegularExpression) query.toRegex().toString() (if (query is SearchQuery.RegularExpression) query.toRegex().toString()
else query.rawText[0] + query.rawText.drop(1).lowercase() else query.rawText[0] + query.rawText.drop(1).lowercase()) + " "
val label2 = NotificationLabel(queryText) val label2 = NotificationLabel(queryText)
val label3 = NotificationLabel( val label3 = NotificationLabel(
"Found ${results.values.flatMap { it.asIterable() }.size}" + "Found ${results.values.flatMap { it.asIterable() }.size}" +
" results in ${results.keys.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 { val panel = JPanel(BorderLayout()).apply {
@@ -120,10 +119,7 @@ internal class TextHighlighter {
if (jumpMode == JumpMode.DISABLED) JBColor.BLACK else jumpMode.caretColor if (jumpMode == JumpMode.DISABLED) JBColor.BLACK else jumpMode.caretColor
) )
preferredSize = Dimension( preferredHeight = label1.preferredSize.height + 10
editor.contentComponent.width +
label1.preferredSize.width, preferredSize.height
)
} }
val hint = LightweightHint(panel) val hint = LightweightHint(panel)