1
0
Fork 0

Compare commits

...

70 Commits

Author SHA1 Message Date
breandan d905909e31 attempt to fix #446 2023-09-16 16:34:46 -04:00
breandan 64c6956b88 add tmux plugins 2023-08-28 21:12:52 -04:00
breandan b1a044dbf8 update change notes 2023-08-28 17:27:29 -04:00
breandan e46cbe1d06 Merge remote-tracking branch 'origin/master' 2023-08-28 17:09:18 -04:00
breandan f64e25a0a9 fixes #442 2023-08-28 17:09:12 -04:00
breandan eba043dfb2
further instructions for locating `AceJump.xml` 2023-08-25 20:54:44 -04:00
breandan a746b0a516
add note about settings deserialization 2023-08-25 09:33:49 -04:00
breandan 209b6c97b7 update versions 2023-08-08 01:19:41 -04:00
breandan 3c89cd07b9 try @YannCebron's solution to #415, pt. II 2023-07-26 22:08:35 -10:00
breandan 2ffcc2c57a try @YannCebron's solution to #415 2023-07-26 21:49:42 -10:00
breandan 56b1dfa9a9 quiet plugin verifier error 2023-06-18 14:22:04 -04:00
breandan 48cadfef4c update versions, acknowledge @wuruofan 2023-06-18 14:11:42 -04:00
breandan 6d47331c71
Merge pull request #440 from wuruofan/master
fix(compatibility): avoid 'java.lang.NoSuchFieldError: Companion' error on lower version IDEA ide
2023-06-18 13:45:42 -04:00
wuruofan 3339f6bdb8 fix(compatibility): avoid 'java.lang.NoSuchFieldError: Companion' error on lower version IDEA ide such as PhpStorm, DevEco Studio etc, which related to `FileEditorManagerEx.getInstanceEx()` companion
Related issues: [#434](https://github.com/acejump/AceJump/issues/434), [#438](https://github.com/acejump/AceJump/issues/438), [#435](https://github.com/acejump/AceJump/issues/435), etc.
2023-06-12 16:34:18 +08:00
breandan e7e85a6944 update to gradle 8.2-rc-2 and new property assignment syntax 2023-06-11 21:42:16 -04:00
breandan 1839efb59f update version 2023-05-28 19:20:17 -04:00
breandan da913f61b6 Merge remote-tracking branch 'origin/master' 2023-05-13 15:04:28 -04:00
breandan 7dd12a0457 fixes #431 2023-05-13 15:04:06 -04:00
breandan dae7bd8fa4 fixes #431 2023-05-13 14:59:39 -04:00
breandan 7d39ea2fef fixes #429 2023-04-28 16:55:42 -04:00
breandan 64ad5039f2 update versions 2023-03-28 23:58:45 -04:00
breandan fb3bfa068e try increasing heap size to appease teamcity? 2023-03-01 14:19:57 -05:00
breandan c52f046a6f switch to K2 compiler 2023-02-14 00:21:43 -05:00
breandan ba739501e8 use BGT and migrate awt.Color to JBColor 2023-02-13 18:45:18 -05:00
breandan e939479368 fixes #426 2023-02-13 16:36:21 -05:00
breandan 1c604ce03c update versions 2023-02-09 16:10:41 -05:00
breandan 099c852e32 Merge remote-tracking branch 'origin/master' 2022-12-29 16:38:27 +11:00
breandan 6642eff1e0 update versions 2022-12-29 16:38:21 +11:00
breandan 73ba06b296
remove duplicate 2022-12-25 17:18:14 +13:00
breandan 9507496092
add Tridactyl 2022-12-25 17:17:30 +13:00
breandan 99e0a50884 fixes #417 2022-12-19 21:30:27 +13:00
breandan c070b211e3 update to latest IDE version 2022-11-30 19:43:24 -05:00
breandan 6a2b5dd422 update build script 2022-11-27 14:05:06 -05:00
breandan b7024842ba add leap and lightspeed 2022-10-13 22:49:12 -04:00
breandan 4831f38b34 update versions and remove unnecessary build instructions 2022-08-22 11:22:17 -04:00
breandan 07014455e6
Merge pull request #410 from AlexPl292/master
Add ids to editor action handlers
2022-08-22 10:59:32 -04:00
Alex Plate ab6c6a702b
Add ids to editor action handlers 2022-08-17 08:20:04 +03:00
breandan 8b9e8bb89b
Merge pull request #409 from colossatr0n/patch-1
Update README.md to specify normal mode mapping for vim-sneak like behavior.
2022-07-24 15:35:48 -04:00
breandan 6c6544cf47 update versions 2022-07-15 23:47:12 -04:00
colossatr0n 7fe9d13f48
Update README.md to specify normal mode mapping for vim-sneak like behavior.
Also update ideavim action syntax to the latest syntax.
2022-07-12 14:23:17 -06:00
breandan f1f9ec5974 fixes #408 2022-06-28 17:53:44 -07:00
breandan 5271d97c00 new kotlin version 2022-06-09 00:55:13 -07:00
breandan 872a99c84c update versions 2022-05-30 07:25:01 -07:00
breandan f8b2db5090
Merge pull request #407 from huoguangjin/master
Remove only the highlighters added by AceJump when the jump session ends
2022-05-16 19:53:40 -04:00
breandan 5f0965c921
update versions 2022-05-16 19:52:12 -04:00
guangjinhuo 5ee0245f0b Add a test case to ensure that other highlighters are not removed #406 2022-04-28 17:30:37 +08:00
guangjinhuo 176d450855 Remove only the highlighters added by AceJump when the jump session ends #406 2022-04-23 15:20:23 +08:00
breandan 1341c6aff4
update version 2022-04-12 12:05:48 -04:00
breandan 0b0622dcdf update anyascii and remove jitpack, fixes anyascii/anyascii#6 2022-04-07 04:00:14 -04:00
breandan 929b08e9d0 update versions 2022-04-05 01:47:41 -04:00
breandan 54ea6ac9c1
Merge pull request #401 from colossatr0n/vim-sneak-bounded-toggle-actions
Add bounded toggle mode classes to start jump mode before the caret or after the caret.
2022-03-27 12:18:56 -04:00
colossatr0n e477a487a2 Add bounded toggle mode classes to start jump mode before the caret or after the caret. 2022-03-27 10:05:42 -06:00
breandan f56dc3d457 fixes #399 2022-03-26 14:39:21 -04:00
breandan 0befd7895e update versions 2022-03-26 14:34:43 -04:00
breandan df94f4ce2a update buildscript as per https://youtrack.jetbrains.com/issue/IDEA-278926#focus=Comments-27-5881199.0-0 2022-03-26 14:26:17 -04:00
breandan 978edff59e update versions and change notes, acknowledge @delphinaubin 2022-03-14 12:42:52 -04:00
breandan f9938590fb
Merge pull request #398 from delphinaubin/add-azerty-key-layout
Add AZERTY keyboard layout (french keyboard)
2022-03-14 12:36:06 -04:00
Delphin Aubin c534192902 Add AZERTY keyboard layout (french keyboard) 2022-02-25 17:01:04 +01:00
breandan 6deac53165 Merge remote-tracking branch 'origin/master' 2022-02-16 04:13:14 -05:00
breandan 2c4d4431bc update versions 2022-02-16 04:13:07 -05:00
breandan 2185da7cb4
Merge pull request #396 from DavidLGoldberg/update-similar-projects-jumpy 2022-02-04 21:27:37 -05:00
David L. Goldberg c2a71a2c43 📝 Update README.md with Jumpy's status
- Jumpy1 is stable and has always been maintained as needed.  Atom's dev has slowed down. Will be fixed as needed.
- Adding Jumpy2.
2022-02-04 19:48:36 -05:00
breandan d29dd3fa34 fixes #392 2021-12-19 12:49:04 -05:00
breandan fdbcea0b4f update IDE version compatibility, fixes #389 2021-12-12 12:12:35 -05:00
breandan c14ae702ba update change notes 2021-12-11 12:30:55 -05:00
breandan 8de4495885 update versions and remove deprecated 2021-12-11 12:06:29 -05:00
breandan dd75e1ddea
update unmaintained and remove canary builds 2021-11-30 00:25:37 -05:00
breandan 02f9ecec5a
update language and reorder 2021-11-30 00:19:23 -05:00
chylex f17f4ef8c4
Fix not highlighting last line
Closes #360
2021-11-21 20:55:19 +01:00
breandan c9034bced6
update changelog 2021-11-21 02:39:25 -05:00
34 changed files with 475 additions and 332 deletions

3
.github/FUNDING.yml vendored
View File

@ -1,3 +0,0 @@
# These are supported funding model platforms
github: breandan

View File

@ -2,14 +2,63 @@
## Unreleased
## 3.8.16
- Fix issue with unselectable tags, [#446](https://github.com/acejump/AceJump/issues/446)
## 3.8.15
- Forbid jumping to offscreen tags, [#442](https://github.com/acejump/AceJump/issues/442)
## 3.8.14
- Fixes NoSuchFieldError: Companion on older platform versions, [#432](https://github.com/acejump/AceJump/issues/432), [#434](https://github.com/acejump/AceJump/issues/434), [#435](https://github.com/acejump/AceJump/issues/432), [#437](https://github.com/acejump/AceJump/issues/437), [#438](https://github.com/acejump/AceJump/issues/438), thanks to [@wuruofan](https://github.com/wuruofan)
## 3.8.13
- Fixes color settings not being persisted, [#431](https://github.com/acejump/AceJump/issues/431)
## 3.8.12
- Fixes tag cycling issue with Enter/Shift+Enter, [#429](https://github.com/acejump/AceJump/issues/429)
## 3.8.11
- Fixes UI issue affecting mode cycling order, [#426](https://github.com/acejump/AceJump/issues/426)
## 3.8.10
- Fixes regression in 3.8.9 breaking cross-tab selection, [#417](https://github.com/acejump/AceJump/issues/417)
## 3.8.9
- Add ids to editor action handlers, [#410](https://github.com/acejump/AceJump/pull/410), thanks to [@AlexPl292](https://github.com/AlexPl292)
- Update API to IJ-2022.3 and JDK to 17
## 3.8.8
- Add AZERTY keyboard layout, [#398](https://github.com/acejump/AceJump/pull/398), thanks to [@delphinaubin](https://github.com/delphinaubin)
- Add bounded toggle mode to start jump mode before or after the caret, [#401](https://github.com/acejump/AceJump/pull/401), thanks to [@colossatr0n](https://github.com/colossatr0n)
- Remove only the highlighters added by AceJump when jump session ends, [#407](https://github.com/acejump/AceJump/pull/407), thanks to [@huoguangjin](https://github.com/huoguangjin)
## 3.8.7
- Fixes Unicode-ASCII regression, [#399](https://github.com/acejump/AceJump/issues/399)
## 3.8.6
- Adds AZERTY keyboard layout, [#398](https://github.com/acejump/AceJump/pull/398), thanks to [@delphinaubin](https://github.com/delphinaubin)
## 3.8.5
- Improves tag order for non-QWERTY layouts, [#385](https://github.com/acejump/AceJump/issues/385)
- Restores <kbd>Tab</kbd>/<kbd>Shift</kbd>+<kbd>Tab</kbd> functionality, [#356](https://github.com/acejump/AceJump/issues/356)
- Fixes tag cycling with <kbd>Enter</kbd>/<kbd>Shift</kbd>+<kbd>Enter</kbd>, [#380](https://github.com/acejump/AceJump/issues/380), thanks [@AlexPl292](https://github.com/AlexPl292)
## 3.8.4
- Fixes Declaration Mode in Rider, [#379](https://github.com/acejump/AceJump/issues/379), thanks to @igor-akhmetov for helping diagnose!
- Fixes highlight offset on high-DPI screens, [#362](https://github.com/acejump/AceJump/issues/362), thanks to @chylex for [the PR](https://github.com/acejump/AceJump/pull/384)!
- Fixes Declaration Mode in Rider, [#379](https://github.com/acejump/AceJump/issues/379), thanks to [@igor-akhmetov](https://github.com/igor-akhmetov) for helping diagnose!
- Fixes highlight offset on high-DPI screens, [#362](https://github.com/acejump/AceJump/issues/362), thanks to [@chylex](https://github.com/chylex) for [the PR](https://github.com/acejump/AceJump/pull/384)!
## 3.8.3
@ -20,7 +69,7 @@
- Add option to display current search text, [#375](https://github.com/acejump/AceJump/issues/375)
- Fixes a bug where editor was not focused, [#374](https://github.com/acejump/AceJump/issues/374)
- Thanks to @SaiKai for the PRs!
- Thanks to [@SaiKai](https://github.com/SaiKai) for the PRs!
## 3.8.1
@ -35,7 +84,7 @@
- Update AceJump extension API to include tag information, [#357](https://github.com/acejump/AceJump/pull/357)
- Allow defining jump mode with boundaries, [#358](https://github.com/acejump/AceJump/pull/358)
- Use Kotlin classes for actions, [#359](https://github.com/acejump/AceJump/pull/359)
- Thanks to @AlexPl292 for the PRs!
- Thanks to [@AlexPl292](https://github.com/AlexPl292) for the PRs!
## 3.7.0
- Improvements to tag latency
@ -49,7 +98,7 @@
- Increase limit for what is considered a large file
- Major refactoring, [#350](https://github.com/acejump/AceJump/pull/353)
- [Many bug fixes](https://github.com/acejump/AceJump/issues/348#issuecomment-739454920): [#338](https://github.com/acejump/AceJump/issues/338), [#336](https://github.com/acejump/AceJump/issues/336), [#329](https://github.com/acejump/AceJump/issues/329), [#327](https://github.com/acejump/AceJump/issues/327), [#310](https://github.com/acejump/AceJump/issues/310), [#233](https://github.com/acejump/AceJump/issues/233), [#228](https://github.com/acejump/AceJump/issues/228), [#187](https://github.com/acejump/AceJump/issues/187), [#147](https://github.com/acejump/AceJump/issues/147), [#132](https://github.com/acejump/AceJump/issues/132), [#71](https://github.com/acejump/AceJump/issues/71)
- Huge thanks to @chylex for [all the PRs](https://github.com/acejump/AceJump/pulls?q=is%3Apr+author%3Achylex)!
- Huge thanks to [@chylex](https://github.com/chylex) for [all the PRs](https://github.com/acejump/AceJump/pulls?q=is%3Apr+author%3Achylex)!
## 3.6.3
@ -59,12 +108,12 @@
## 3.6.2
- Fixes [#226](https://github.com/acejump/AceJump/issues/226). Thanks @AlexPl292!
- Fixes [#226](https://github.com/acejump/AceJump/issues/226). Thanks [@AlexPl292](https://github.com/AlexPl292)!
- Update Pinyin engine.
## 3.6.1
- Fixes [#324](https://github.com/acejump/AceJump/issues/324). Thanks @AlexPl292!
- Fixes [#324](https://github.com/acejump/AceJump/issues/324). Thanks [@AlexPl292](https://github.com/AlexPl292)!
- Fixes [#325](https://github.com/acejump/AceJump/issues/325).
- Fixes Pinyin support.
@ -72,7 +121,7 @@
- Adds support for Chinese [#314](https://github.com/acejump/AceJump/issues/314).
- Fixes constantly loading settings page [#303](https://github.com/acejump/AceJump/issues/303).
- Honor camel humps [#315](https://github.com/acejump/AceJump/issues/315). Thanks to @clojj.
- Honor camel humps [#315](https://github.com/acejump/AceJump/issues/315). Thanks to [@clojj](https://github.com/clojj).
- Support dynamic application reloading [#322](https://github.com/acejump/AceJump/issues/322).
## 3.5.9

View File

@ -1,13 +1,20 @@
<p align="center"><a href="https://plugins.jetbrains.com/plugin/7086"> <img src="logo.png" alt="AceJumpLogo"></a></p>
<p align="center">
<a href="https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub" title="JetBrains on GitHub"><img src="http://jb.gg/badges/team.svg"></a>
<a href="https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub" title="JetBrains on GitHub"><img src="https://jb.gg/badges/team.svg"></a>
<a href="https://teamcity.jetbrains.com/viewType.html?buildTypeId=acejump_buildplugin&guest=1" title="Build Plugin"><img src="https://teamcity.jetbrains.com/app/rest/builds/buildType:acejump_buildplugin/statusIcon.svg"></a>
<a href="https://plugins.jetbrains.com/plugin/7086-acejump" title="Jetbrains Plugin"><img src="https://img.shields.io/jetbrains/plugin/v/7086-acejump.svg"></a>
<a href="LICENSE" title="License"><img src="https://img.shields.io/badge/License-GPL%20v3-blue.svg"></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>
> **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:
![](https://cloud.githubusercontent.com/assets/175716/20177444/124fb534-a74d-11e6-8912-1d220ae27091.png)
@ -28,7 +35,7 @@ AceJump search is [smart case](http://ideavim.sourceforge.net/vim/usr_27.html#vi
## Tips
- Press <kbd>Tab</kbd> when searching to jump to the next group of matches in the editor. *This feature is unavailable in `3.6.4-3.8.4`.*
- Press <kbd>Tab</kbd> when searching to jump to the next group of matches in the editor.
- If you make a mistake searching, just press <kbd>Backspace</kbd> to restart from scratch.
@ -54,8 +61,6 @@ AceJump search is [smart case](http://ideavim.sourceforge.net/vim/usr_27.html#vi
AceJump can be [installed directly from the IDE](https://www.jetbrains.com/help/idea/managing-plugins.html#install), via **Settings | Plugins | Browse Repositories... | 🔍 "AceJump"**.
[Canary builds](https://teamcity.jetbrains.com/repository/download/acejump_buildplugin/.lastSuccessful/AceJump.zip?guest=1) are provided courtesy of [TeamCity](https://www.jetbrains.com/teamcity/). These can be downloaded and [installed from disk](https://www.jetbrains.com/help/idea/managing-plugins.html#install_plugin_from_disk).
## Configuring
[IdeaVim](https://plugins.jetbrains.com/plugin/164) users can choose to activate AceJump with a single keystroke (<kbd>f</kbd>, <kbd>F</kbd> and <kbd>g</kbd> are arbitrary) by running:
@ -64,15 +69,25 @@ AceJump can be [installed directly from the IDE](https://www.jetbrains.com/help/
echo -e '
" Press `f` to activate AceJump
map f :action AceAction<CR>
map f <Action>(AceAction)
" Press `F` to activate Target Mode
map F :action AceTargetAction<CR>
map F <Action>(AceTargetAction)
" Press `g` to activate Line Mode
map g :action AceLineAction<CR>
map g <Action>(AceLineAction)
' >> ~/.ideavimrc
```
To customize AceJump's behavior further with additional actions, see the `<action>` tags in [plugin.xml](src/main/resources/META-INF/plugin.xml). The following example shows how to activate AceJump before or after the caret.
```
" Press `S` in normal mode to activate AceJump mode before the caret
nmap S <Action>(AceBackwardAction)
" Press `s` in normal mode to activate AceJump mode after the caret
nmap s <Action>(AceForwardAction)
```
To change the default keyboard shortcuts, open **File \| Settings \| Keymap \| 🔍 "AceJump" \| AceJump \|** <kbd>Enter⏎</kbd>.
![Keymap](https://cloud.githubusercontent.com/assets/175716/11760350/911aed4c-a065-11e5-8f17-49bc97ad1dad.png)
@ -171,31 +186,37 @@ The following plugins have a similar UI for navigating text and web browsing:
|:----------------------------------------------------------------------|:-------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------:|:-------------------:|:------------------------------------------------------------------------:|
| 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/) |
| [AceJump-Lite](https://github.com/EeeMt/AceJump-Lite) | [](https://plugins.jetbrains.com/plugin/9803-acejump-lite) | [IntelliJ Platform](https://jetbrains.com) | :heavy_check_mark: | [Java](https://www.java.com) |
| [KJump](https://github.com/a690700752/KJump) | [](https://plugins.jetbrains.com/plugin/10149-kjump) | [IntelliJ Platform](https://jetbrains.com) | :heavy_check_mark: | [Java](https://www.java.com) |
| [emacsIDEAs](https://github.com/whunmr/emacsIDEAs) | [](https://plugins.jetbrains.com/plugin/7163-emacsideas) | [IntelliJ Platform](https://jetbrains.com) | :heavy_check_mark: | [Java](https://www.java.com) |
| [TraceJump](https://github.com/acejump/tracejump) | [](https://github.com/acejump/tracejump) | Desktop | :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/) |
| [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/) |
| [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/) |
| [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) |
| [Sublime EasyMotion](https://github.com/tednaleid/sublime-EasyMotion) | [](https://packagecontrol.io/packages/EasyMotion) | [Sublime](https://www.sublimetext.com/) | :x: | [Python](https://www.python.org/) |
| [AceJump](https://github.com/ice9js/ace-jump-sublime) | [](https://packagecontrol.io/packages/AceJump) | [Sublime](https://www.sublimetext.com/) | :heavy_check_mark: | [Python](https://www.python.org/) |
| [Jumpy](https://github.com/DavidLGoldberg/jumpy) | [](https://atom.io/packages/jumpy) | [Atom](https://atom.io/) | :heavy_check_mark: | [CoffeeScript](http://coffeescript.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/) |
| [Jumpy](https://github.com/DavidLGoldberg/jumpy) | [](https://atom.io/packages/jumpy) | [Atom](https://atom.io/) | :heavy_check_mark: | [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/) |
| [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/) |
| [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/) |
| [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/) |
| [CodeAceJumper](https://github.com/lucax88x/CodeAceJumper) | [](https://marketplace.visualstudio.com/items?itemName=lucax88x.codeacejumper) | [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/) |
| [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/) |
| [cVim](https://github.com/1995eaton/chromium-vim) | [](https://chrome.google.com/webstore/detail/cvim/ihlenndgcmojhcghmfjfneahoeklbjjh) | [Chrome](https://www.google.com/chrome) | :heavy_check_mark: | [JavaScript](https://www.javascript.com/) |
| [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-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) |
| [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/) |
| [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.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/) |
| [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/) |

View File

@ -1,73 +1,93 @@
import org.jetbrains.changelog.*
import org.jetbrains.intellij.tasks.*
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.changelog.Changelog.OutputType.HTML
import org.jetbrains.changelog.date
plugins {
idea apply true
kotlin("jvm") version "1.6.0-RC2"
id("org.jetbrains.intellij") version "1.2.1"
id("org.jetbrains.changelog") version "1.3.1"
id("com.github.ben-manes.versions") version "0.39.0"
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"
}
tasks {
withType<KotlinCompile> {
kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8.toString()
compileKotlin {
kotlinOptions.jvmTarget = JavaVersion.VERSION_17.toString()
}
named<Zip>("buildPlugin") {
dependsOn("test")
archiveFileName.set("AceJump.zip")
archiveFileName = "AceJump.zip"
}
withType<RunIdeTask> {
runIde {
dependsOn("test")
findProperty("luginDev")?.let { args = listOf(projectDir.absolutePath) }
}
publishPlugin {
val intellijPublishToken: String? by project
token.set(intellijPublishToken)
token = intellijPublishToken
}
patchPluginXml {
sinceBuild.set("203.7717.56")
changeNotes.set(provider {
changelog.getAll().values.take(2).last().toHTML()
})
sinceBuild = "223.7571.182"
changeNotes = provider {
changelog.renderItem(changelog.getAll().values.take(2).last(), HTML)
}
}
runPluginVerifier {
ideVersions.set(listOf("2021.2.1"))
ideVersions = listOf("2023.2")
}
// Remove pending: https://youtrack.jetbrains.com/issue/IDEA-278926
val test by getting(Test::class) {
isScanForTestClasses = false
// Only run tests from classes that end with "Test"
include("**/AceTest.class")
include("**/ExternalUsageTest.class")
include("**/LatencyTest.class")
}
}
kotlin {
jvmToolchain {
run {
languageVersion = JavaLanguageVersion.of(17)
}
}
sourceSets.all {
languageSettings.apply {
languageVersion = "2.0"
}
}
}
val acejumpVersion = "3.8.16"
changelog {
version.set("3.8.5")
path.set("${project.projectDir}/CHANGES.md")
header.set(provider { "[${project.version}] - ${date()}" })
itemPrefix.set("-")
unreleasedTerm.set("Unreleased")
version = acejumpVersion
path = "${project.projectDir}/CHANGES.md"
header = provider { "[${project.version}] - ${date()}" }
itemPrefix = "-"
unreleasedTerm = "Unreleased"
}
repositories {
mavenCentral()
maven("https://jitpack.io")
}
dependencies {
// gradle-intellij-plugin doesn't attach sources properly for Kotlin :(
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
compileOnly(kotlin("stdlib-jdk8"))
implementation("com.anyascii:anyascii:0.3.0")
// https://github.com/anyascii/anyascii
implementation("com.anyascii:anyascii:0.3.2")
}
intellij {
version.set("2021.2.1")
pluginName.set("AceJump")
updateSinceUntilBuild.set(false)
plugins.set(listOf("java"))
version = "2023.2.1"
pluginName = "AceJump"
updateSinceUntilBuild = false
plugins = listOf("java")
}
group = "org.acejump"
version = "3.8.5"
version = acejumpVersion

1
gradle.properties Normal file
View File

@ -0,0 +1 @@
org.gradle.jvmargs=-Xmx2048m

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -2,9 +2,11 @@ package org.acejump
import com.anyascii.AnyAscii
import com.intellij.diff.util.DiffUtil.getLineCount
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.*
import it.unimi.dsi.fastutil.ints.IntArrayList
import org.acejump.config.AceConfig
import java.awt.Point
import kotlin.math.*
/**
@ -127,18 +129,15 @@ fun Editor.offsetCenter(first: Int, second: Int): LogicalPosition {
return offsetToLogicalPosition(getLineStartOffset(center))
}
// Borrowed from Editor.calculateVisibleRange() but only available after 232.6095.10
fun Editor.getView(): IntRange {
val firstVisibleLine = max(0, getVisualLineAtTopOfScreen() - 1)
val firstLine = visualLineToLogicalLine(firstVisibleLine)
val startOffset = getLineStartOffset(firstLine)
val height = getScreenHeight() + 2
val lastLine = visualLineToLogicalLine(firstVisibleLine + height)
var endOffset = getLineEndOffset(lastLine, true)
endOffset = normalizeOffset(lastLine, endOffset)
endOffset = min(max(0, document.textLength - 1), endOffset + 1)
return startOffset..endOffset
ApplicationManager.getApplication().assertIsDispatchThread()
val rect = scrollingModel.visibleArea
val startPosition = xyToLogicalPosition(Point(rect.x, rect.y))
val visibleStart = logicalPositionToOffset(startPosition)
val endPosition = xyToLogicalPosition(Point(rect.x + rect.width, rect.y + rect.height))
val visibleEnd = logicalPositionToOffset(LogicalPosition(endPosition.line + 1, 0))
return visibleStart..visibleEnd
}
/**

View File

@ -1,17 +1,30 @@
package org.acejump.action
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR
import com.intellij.openapi.actionSystem.PlatformDataKeys.LAST_ACTIVE_FILE_EDITOR
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.fileEditor.TextEditor
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.util.IncorrectOperationException
import org.acejump.boundaries.Boundaries
import org.acejump.boundaries.StandardBoundaries.*
import org.acejump.boundaries.StandardBoundaries.AFTER_CARET
import org.acejump.boundaries.StandardBoundaries.BEFORE_CARET
import org.acejump.boundaries.StandardBoundaries.WHOLE_FILE
import org.acejump.input.JumpMode
import org.acejump.input.JumpMode.*
import org.acejump.input.JumpMode.DECLARATION
import org.acejump.input.JumpMode.JUMP
import org.acejump.input.JumpMode.JUMP_END
import org.acejump.input.JumpMode.TARGET
import org.acejump.search.Pattern
import org.acejump.search.Pattern.*
import org.acejump.search.Pattern.ALL_WORDS
import org.acejump.search.Pattern.LINE_ALL_MARKS
import org.acejump.search.Pattern.LINE_ENDS
import org.acejump.search.Pattern.LINE_INDENTS
import org.acejump.search.Pattern.LINE_STARTS
import org.acejump.session.Session
import org.acejump.session.SessionManager
@ -19,25 +32,28 @@ import org.acejump.session.SessionManager
* Base class for keyboard-activated actions that create or update an AceJump [Session].
*/
sealed class AceAction: DumbAwareAction() {
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
final override fun update(action: AnActionEvent) {
action.presentation.isEnabled = action.getData(EDITOR) != null
action.presentation.isEnabled =
(action.getData(EDITOR) ?: (action.getData(LAST_ACTIVE_FILE_EDITOR) as? TextEditor)?.editor) != null
}
final override fun actionPerformed(e: AnActionEvent) {
val editor = e.getData(EDITOR) ?: return
val editor = e.getData(EDITOR) ?: (e.getData(LAST_ACTIVE_FILE_EDITOR) as? TextEditor)?.editor ?: return
val project = e.project
if (project != null) {
try {
val openEditors = FileEditorManagerEx.getInstanceEx(project).splitters.selectedEditors
val fem = FileEditorManager.getInstance(project) as FileEditorManagerEx
val openEditors = fem.splitters.getSelectedEditors()
.mapNotNull { (it as? TextEditor)?.editor }
.sortedBy { if (it === editor) 0 else 1 }
invoke(SessionManager.start(editor, openEditors))
} catch (e: IncorrectOperationException) {
invoke(SessionManager.start(editor))
}
}
else {
} else {
invoke(SessionManager.start(editor))
}
}
@ -51,6 +67,13 @@ sealed class AceAction: DumbAwareAction() {
final override fun invoke(session: Session) = session.toggleJumpMode(mode)
}
/**
* Generic action type that toggles a specific [JumpMode] with [Boundaries].
*/
abstract class BaseToggleBoundedJumpModeAction(private val mode: JumpMode, private val boundaries: Boundaries): AceAction() {
final override fun invoke(session: Session) = session.toggleJumpMode(mode, boundaries)
}
/**
* Generic action type that starts a regex search.
*/
@ -74,12 +97,17 @@ sealed class AceAction: DumbAwareAction() {
// @formatter:off
// Unbounded Toggle Modes
class ToggleJumpMode : BaseToggleJumpModeAction(JUMP)
class ToggleJumpEndMode : BaseToggleJumpModeAction(JUMP_END)
class ToggleTargetMode : BaseToggleJumpModeAction(TARGET)
class ToggleDeclarationMode : BaseToggleJumpModeAction(DECLARATION)
// Bounded Toggle Modes
class ToggleBackwardJumpMode : BaseToggleBoundedJumpModeAction(JUMP, BEFORE_CARET)
class ToggleForwardJumpMode : BaseToggleBoundedJumpModeAction(JUMP, AFTER_CARET)
// Regex Modes
class StartAllWordsMode : BaseRegexSearchAction(ALL_WORDS, WHOLE_FILE)
class StartAllWordsBackwardsMode : BaseRegexSearchAction(ALL_WORDS, BEFORE_CARET)
class StartAllWordsForwardMode : BaseRegexSearchAction(ALL_WORDS, AFTER_CARET)

View File

@ -1,22 +1,31 @@
package org.acejump.action
import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.actionSystem.IdeActions.*
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.IdeActions.ACTION_GOTO_DECLARATION
import com.intellij.openapi.actionSystem.IdeActions.ACTION_GOTO_TYPE_DECLARATION
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.command.UndoConfirmationPolicy
import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.fileEditor.TextEditor
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.playback.commands.ActionCommand
import org.acejump.*
import org.acejump.countMatchingCharacters
import org.acejump.immutableText
import org.acejump.input.JumpMode
import org.acejump.input.JumpMode.*
import org.acejump.input.JumpMode.DECLARATION
import org.acejump.input.JumpMode.JUMP_END
import org.acejump.input.JumpMode.TARGET
import org.acejump.isWordPart
import org.acejump.search.SearchProcessor
import org.acejump.search.Tag
import org.acejump.wordEnd
import org.acejump.wordStart
/**
* Performs [JumpMode] navigation and actions.
@ -28,7 +37,7 @@ internal class TagJumper(private val mode: JumpMode, private val searchProcessor
fun visit(tag: Tag) {
val editor = tag.editor
val offset = tag.offset
if (mode === JUMP_END || mode === TARGET) {
val chars = editor.immutableText
val matchingChars = searchProcessor?.let { chars.countMatchingCharacters(offset, it.query.rawText) } ?: 0
@ -95,12 +104,12 @@ internal class TagJumper(private val mode: JumpMode, private val searchProcessor
selectionModel.setSelection(fromOffset, toOffset)
caretModel.moveToOffset(toOffset)
}
private fun ensureEditorFocused(editor: Editor) {
val project = editor.project ?: return
val fem = FileEditorManagerEx.getInstanceEx(project)
val window = fem.windows.firstOrNull { (it.selectedEditor?.selectedWithProvider?.fileEditor as? TextEditor)?.editor === editor }
val fem = FileEditorManager.getInstance(project) as FileEditorManagerEx
val window = fem.windows.firstOrNull { (it.getSelectedComposite(false)?.selectedWithProvider?.fileEditor as? TextEditor)?.editor === editor }
if (window != null && window !== fem.currentWindow) {
fem.currentWindow = window
}

View File

@ -5,10 +5,10 @@ import org.acejump.*
import org.acejump.search.SearchProcessor
internal class TagScroller(private val editor: Editor, private val searchProcessor: SearchProcessor) {
fun scroll(forward: Boolean = true): Boolean {
val position = if (forward) findNextPosition() else findPreviousPosition()
return if (position != null) true.also { scrollTo(position) } else false
}
fun scroll(
forward: Boolean = true,
position: LogicalPosition? = if (forward) findNextPosition() else findPreviousPosition()
) = if (position != null) true.also { scrollTo(position) } else false
private fun scrollTo(position: LogicalPosition) = editor.run {
scrollingModel.disableAnimation()

View File

@ -2,7 +2,6 @@ package org.acejump.action
import com.intellij.openapi.editor.*
import com.intellij.openapi.editor.ScrollType.*
import org.acejump.*
import org.acejump.search.SearchProcessor
import org.acejump.search.Tag
import kotlin.math.abs

View File

@ -16,12 +16,14 @@ interface Boundaries {
* offsets outside the boundary, for ex. when the boundary is rectangular
* and the file has long lines which are only partially visible.
*/
fun getOffsetRange(editor: Editor, cache: EditorOffsetCache = EditorOffsetCache.Uncached): IntRange
fun getOffsetRange(editor: Editor, cache: EditorOffsetCache = EditorOffsetCache.Uncached): IntRange =
StandardBoundaries.VISIBLE_ON_SCREEN.getOffsetRange(editor, cache)
/**
* Returns whether the editor offset is included within the boundary.
*/
fun isOffsetInside(editor: Editor, offset: Int, cache: EditorOffsetCache = EditorOffsetCache.Uncached): Boolean
fun isOffsetInside(editor: Editor, offset: Int, cache: EditorOffsetCache = EditorOffsetCache.Uncached): Boolean =
StandardBoundaries.VISIBLE_ON_SCREEN.isOffsetInside(editor, offset, cache)
/**
* Creates a boundary so that an offset/range is within the boundary

View File

@ -30,9 +30,7 @@ sealed class EditorOffsetCache {
*/
abstract fun offsetToXY(editor: Editor, offset: Int): Point
companion object {
fun new(): EditorOffsetCache = Cache()
}
companion object { fun new(): EditorOffsetCache = Cache() }
private class Cache: EditorOffsetCache() {
private var visibleArea: Pair<Point, Point>? = null
@ -45,17 +43,13 @@ sealed class EditorOffsetCache {
override fun xyToOffset(editor: Editor, pos: Point): Int =
pointToOffset.getInt(pos).let { offset ->
if (offset != -1) offset
else Uncached.xyToOffset(editor, pos).also {
@Suppress("ReplacePutWithAssignment")
pointToOffset.put(pos, it)
}
else Uncached.xyToOffset(editor, pos)
.also { pointToOffset.put(pos, it) }
}
override fun offsetToXY(editor: Editor, offset: Int) =
offsetToPoint.get(offset) ?: Uncached.offsetToXY(editor, offset).also {
@Suppress("ReplacePutWithAssignment")
offsetToPoint.put(offset, it)
}
offsetToPoint.get(offset) ?: Uncached.offsetToXY(editor, offset)
.also { offsetToPoint.put(offset, it) }
}
object Uncached: EditorOffsetCache() {

View File

@ -5,10 +5,10 @@ import com.intellij.openapi.editor.Editor
enum class StandardBoundaries : Boundaries {
WHOLE_FILE {
override fun getOffsetRange(editor: Editor, cache: EditorOffsetCache) =
0 until editor.document.textLength
0..editor.document.textLength
override fun isOffsetInside(editor: Editor, offset: Int, cache: EditorOffsetCache) =
offset in (0 until editor.document.textLength)
offset in (0..editor.document.textLength)
},
VISIBLE_ON_SCREEN {

View File

@ -1,9 +1,9 @@
package org.acejump.config
import com.intellij.openapi.components.PersistentStateComponent
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.components.State
import com.intellij.openapi.components.Storage
import com.intellij.util.application
import org.acejump.input.KeyLayoutCache
/**
@ -16,19 +16,19 @@ class AceConfig: PersistentStateComponent<AceSettings> {
private var aceSettings = AceSettings()
companion object {
val settings get() = ServiceManager.getService(AceConfig::class.java).aceSettings
val settings get() = application.getService(AceConfig::class.java).aceSettings
// @formatter:off
val layout get() = settings.layout
val cycleModes get() = settings.let { arrayOf(it.cycleMode1, it.cycleMode2, it.cycleMode3, it.cycleMode4) }
val minQueryLength get() = settings.minQueryLength
val jumpModeColor get() = settings.jumpModeColor
val jumpEndModeColor get() = settings.jumpEndModeColor
val targetModeColor get() = settings.targetModeColor
val definitionModeColor get() = settings.definitionModeColor
val textHighlightColor get() = settings.textHighlightColor
val tagForegroundColor get() = settings.tagForegroundColor
val tagBackgroundColor get() = settings.tagBackgroundColor
val jumpModeColor get() = settings.getJumpModeJBC()
val jumpEndModeColor get() = settings.getJumpEndModeJBC()
val targetModeColor get() = settings.getTargetModeJBC()
val definitionModeColor get() = settings.getDefinitionModeJBC()
val textHighlightColor get() = settings.getTextHighlightJBC()
val tagForegroundColor get() = settings.getTagForegroundJBC()
val tagBackgroundColor get() = settings.getTagBackgroundJBC()
val searchWholeFile get() = settings.searchWholeFile
val mapToASCII get() = settings.mapToASCII
val showSearchNotification get() = settings.showSearchNotification

View File

@ -19,13 +19,13 @@ class AceConfigurable: Configurable {
panel.cycleMode3 != settings.cycleMode3 ||
panel.cycleMode4 != settings.cycleMode4 ||
panel.minQueryLengthInt != settings.minQueryLength ||
panel.jumpModeColor != settings.jumpModeColor ||
panel.jumpEndModeColor != settings.jumpEndModeColor ||
panel.targetModeColor != settings.targetModeColor ||
panel.definitionModeColor != settings.definitionModeColor ||
panel.textHighlightColor != settings.textHighlightColor ||
panel.tagForegroundColor != settings.tagForegroundColor ||
panel.tagBackgroundColor != settings.tagBackgroundColor ||
panel.jumpModeColor?.rgb != settings.jumpModeColor ||
panel.jumpEndModeColor?.rgb != settings.jumpEndModeColor ||
panel.targetModeColor?.rgb != settings.targetModeColor ||
panel.definitionModeColor?.rgb != settings.definitionModeColor ||
panel.textHighlightColor?.rgb != settings.textHighlightColor ||
panel.tagForegroundColor?.rgb != settings.tagForegroundColor ||
panel.tagBackgroundColor?.rgb != settings.tagBackgroundColor ||
panel.searchWholeFile != settings.searchWholeFile ||
panel.mapToASCII != settings.mapToASCII ||
panel.showSearchNotification != settings.showSearchNotification
@ -38,13 +38,13 @@ class AceConfigurable: Configurable {
settings.cycleMode3 = panel.cycleMode3
settings.cycleMode4 = panel.cycleMode4
settings.minQueryLength = panel.minQueryLengthInt ?: settings.minQueryLength
panel.jumpModeColor?.let { settings.jumpModeColor = it }
panel.jumpEndModeColor?.let { settings.jumpEndModeColor = it }
panel.targetModeColor?.let { settings.targetModeColor = it }
panel.definitionModeColor?.let { settings.definitionModeColor = it }
panel.textHighlightColor?.let { settings.textHighlightColor = it }
panel.tagForegroundColor?.let { settings.tagForegroundColor = it }
panel.tagBackgroundColor?.let { settings.tagBackgroundColor = it }
panel.jumpModeColor?.let { settings.jumpModeColor = it.rgb }
panel.jumpEndModeColor?.let { settings.jumpEndModeColor = it.rgb }
panel.targetModeColor?.let { settings.targetModeColor = it.rgb }
panel.definitionModeColor?.let { settings.definitionModeColor = it.rgb }
panel.textHighlightColor?.let { settings.textHighlightColor = it.rgb }
panel.tagForegroundColor?.let { settings.tagForegroundColor = it.rgb }
panel.tagBackgroundColor?.let { settings.tagBackgroundColor = it.rgb }
settings.searchWholeFile = panel.searchWholeFile
settings.mapToASCII = panel.mapToASCII
settings.showSearchNotification = panel.showSearchNotification

View File

@ -1,11 +1,8 @@
package org.acejump.config
import com.intellij.util.xmlb.Converter
import com.intellij.util.xmlb.annotations.OptionTag
import org.acejump.input.JumpMode
import org.acejump.input.KeyLayout
import com.intellij.ui.JBColor
import org.acejump.input.*
import org.acejump.input.KeyLayout.QWERTY
import java.awt.Color
data class AceSettings(
var layout: KeyLayout = QWERTY,
@ -16,35 +13,31 @@ data class AceSettings(
var cycleMode4: JumpMode = JumpMode.JUMP_END,
var minQueryLength: Int = 1,
@OptionTag("jumpModeRGB", converter = ColorConverter::class)
var jumpModeColor: Color = Color(0xFFFFFF),
var jumpModeColor: Int = 0xFFFFFF,
@OptionTag("jumpEndModeRGB", converter = ColorConverter::class)
var jumpEndModeColor: Color = Color(0x33E78A),
var jumpEndModeColor: Int = 0x33E78A,
@OptionTag("targetModeRGB", converter = ColorConverter::class)
var targetModeColor: Color = Color(0xFFB700),
var targetModeColor: Int = 0xFFB700,
@OptionTag("definitionModeRGB", converter = ColorConverter::class)
var definitionModeColor: Color = Color(0x6FC5FF),
var definitionModeColor: Int = 0x6FC5FF,
@OptionTag("textHighlightRGB", converter = ColorConverter::class)
var textHighlightColor: Color = Color(0x394B58),
var textHighlightColor: Int = 0x394B58,
@OptionTag("tagForegroundRGB", converter = ColorConverter::class)
var tagForegroundColor: Color = Color(0xFFFFFF),
var tagForegroundColor: Int = 0xFFFFFF,
@OptionTag("tagBackgroundRGB", converter = ColorConverter::class)
var tagBackgroundColor: Color = Color(0x008299),
var tagBackgroundColor: Int = 0x008299,
var searchWholeFile: Boolean = true,
var mapToASCII : Boolean = false,
var mapToASCII: Boolean = false,
var showSearchNotification : Boolean = false
)
internal class ColorConverter: Converter<Color>() {
override fun toString(value: Color) = value.rgb.toString()
override fun fromString(value: String) = value.toIntOrNull()?.let(::Color)
var showSearchNotification: Boolean = false
) {
fun getJumpModeJBC() = JBColor.namedColor("jumpModeRGB", jumpModeColor)
fun getJumpEndModeJBC() = JBColor.namedColor("jumpEndModeRGB", jumpEndModeColor)
fun getTargetModeJBC() = JBColor.namedColor("targetModeRGB", targetModeColor)
fun getDefinitionModeJBC() = JBColor.namedColor("definitionModeRGB", definitionModeColor)
fun getTextHighlightJBC() = JBColor.namedColor("textHighlightRGB", textHighlightColor)
fun getTagForegroundJBC() = JBColor.namedColor("tagForegroundRGB", tagForegroundColor)
fun getTagBackgroundJBC() = JBColor.namedColor("tagBackgroundRGB", tagBackgroundColor)
}

View File

@ -2,20 +2,11 @@ package org.acejump.config
import com.intellij.openapi.ui.ComboBox
import com.intellij.ui.ColorPanel
import com.intellij.ui.components.JBCheckBox
import com.intellij.ui.components.JBTextArea
import com.intellij.ui.components.JBTextField
import com.intellij.ui.layout.Cell
import com.intellij.ui.layout.GrowPolicy.MEDIUM_TEXT
import com.intellij.ui.layout.GrowPolicy.SHORT_TEXT
import com.intellij.ui.layout.panel
import org.acejump.input.JumpMode
import org.acejump.input.KeyLayout
import java.awt.Color
import java.awt.Font
import javax.swing.JCheckBox
import javax.swing.JComponent
import javax.swing.JPanel
import com.intellij.ui.components.*
import com.intellij.ui.dsl.builder.*
import org.acejump.input.*
import java.awt.*
import javax.swing.*
import javax.swing.text.JTextComponent
import kotlin.reflect.KProperty
@ -54,45 +45,40 @@ internal class AceSettingsPanel {
}
internal val rootPanel: JPanel = panel {
fun Cell.short(component: JComponent) = component(growPolicy = SHORT_TEXT)
fun Cell.medium(component: JComponent) = component(growPolicy = MEDIUM_TEXT)
titledRow("Characters and Layout") {
row("Allowed characters in tags:") { medium(tagCharsField) }
row("Keyboard layout:") { short(keyboardLayoutCombo) }
row("Keyboard design:") { short(keyboardLayoutArea) }
group("Characters and Layout") {
row("Allowed characters in tags:") { cell(tagCharsField).columns(COLUMNS_LARGE) }
row("Keyboard layout:") { cell(keyboardLayoutCombo).columns(COLUMNS_SHORT) }
row("Keyboard design:") { cell(keyboardLayoutArea).columns(COLUMNS_SHORT) }
}
titledRow("Modes") {
row("Cycle order:") { cell { cycleModeCombo1() } }
row("") {
cell(isVerticalFlow = true) {
cycleModeCombo2()
cycleModeCombo3()
cycleModeCombo4()
}
group("Modes") {
row("Cycle order:") {
cell(cycleModeCombo1).columns(10)
cell(cycleModeCombo2).columns(10)
cell(cycleModeCombo3).columns(10)
cell(cycleModeCombo4).columns(10)
}
}
titledRow("Colors") {
row("Jump mode caret background:") { short(jumpModeColorWheel) }
row("Jump to End mode caret background:") { short(jumpEndModeColorWheel) }
row("Target mode caret background:") { short(targetModeColorWheel) }
row("Definition mode caret background:") { short(definitionModeColorWheel) }
row("Searched text background:") { short(textHighlightColorWheel) }
row("Tag foreground:") { short(tagForegroundColorWheel) }
row("Tag background:") { short(tagBackgroundColorWheel) }
group("Colors") {
row("Jump mode caret background:") { cell(jumpModeColorWheel) }
row("Jump to End mode caret background:") { cell(jumpEndModeColorWheel) }
row("Target mode caret background:") { cell(targetModeColorWheel) }
row("Definition mode caret background:") { cell(definitionModeColorWheel) }
row("Searched text background:") { cell(textHighlightColorWheel) }
row("Tag foreground:") { cell(tagForegroundColorWheel) }
row("Tag background:") { cell(tagBackgroundColorWheel) }
}
titledRow("Behavior") {
row { short(searchWholeFileCheckBox.apply { text = "Search whole file" }) }
row("Minimum typed characters (1-10):") { short(minQueryLengthField) }
group("Behavior") {
row { cell(searchWholeFileCheckBox.apply { text = "Search whole file" }) }
row("Minimum typed characters (1-10):") { cell(minQueryLengthField) }
}
titledRow("Language Settings") {
row { short(mapToASCIICheckBox.apply { text = "Map unicode to ASCII" }) }
group("Language Settings") {
row { cell(mapToASCIICheckBox.apply { text = "Map unicode to ASCII" }) }
}
titledRow("Visual") {
row { short(showSearchNotificationCheckBox.apply { text = "Show hint with search text" }) }
group("Visual") {
row { cell(showSearchNotificationCheckBox.apply { text = "Show hint with search text" }) }
}
}
@ -130,13 +116,13 @@ internal class AceSettingsPanel {
cycleMode3 = settings.cycleMode3
cycleMode4 = settings.cycleMode4
minQueryLength = settings.minQueryLength.toString()
jumpModeColor = settings.jumpModeColor
jumpEndModeColor = settings.jumpEndModeColor
targetModeColor = settings.targetModeColor
definitionModeColor = settings.definitionModeColor
textHighlightColor = settings.textHighlightColor
tagForegroundColor = settings.tagForegroundColor
tagBackgroundColor = settings.tagBackgroundColor
jumpModeColor = settings.getJumpModeJBC()
jumpEndModeColor = settings.getJumpEndModeJBC()
targetModeColor = settings.getTargetModeJBC()
definitionModeColor = settings.getDefinitionModeJBC()
textHighlightColor = settings.getTextHighlightJBC()
tagForegroundColor = settings.getTagForegroundJBC()
tagBackgroundColor = settings.getTagBackgroundJBC()
searchWholeFile = settings.searchWholeFile
mapToASCII = settings.mapToASCII
showSearchNotification = settings.showSearchNotification

View File

@ -61,20 +61,19 @@ enum class JumpMode {
*/
DECLARATION;
val caretColor: Color
get() = when (this) {
JUMP -> AceConfig.jumpModeColor
JUMP_END -> AceConfig.jumpEndModeColor
DECLARATION -> AceConfig.definitionModeColor
TARGET -> AceConfig.targetModeColor
DISABLED -> AbstractColorsScheme.INHERITED_COLOR_MARKER
}
val caretColor: Color get() = when (this) {
DISABLED -> AbstractColorsScheme.INHERITED_COLOR_MARKER
JUMP -> AceConfig.jumpModeColor
JUMP_END -> AceConfig.jumpEndModeColor
TARGET -> AceConfig.targetModeColor
DECLARATION -> AceConfig.definitionModeColor
}
override fun toString() = when (this) {
DISABLED -> "(Skip)"
JUMP -> "Jump"
JUMP_END -> "Jump to End"
TARGET -> "Target"
DECLARATION -> "Definition"
DISABLED -> "(Skip)"
JUMP -> "Jump"
JUMP_END -> "Jump to End"
TARGET -> "Target"
DECLARATION -> "Definition"
}
}

View File

@ -19,42 +19,43 @@ enum class KeyLayout(internal val rows: Array<String>, priority: String) {
QWERTZ(arrayOf("1234567890", "qwertzuiop", "asdfghjkl", "yxcvbnm"), priority = "fjghdkslavncmbxyrutzeiwoqp5849673210"),
QGMLWY(arrayOf("1234567890", "qgmlwyfub", "dstnriaeoh", "zxcvjkp"), priority = "naterisodhvkcpjxzlfmuwygbq5849673210"),
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");
internal val allChars = rows.joinToString("").toCharArray().apply(CharArray::sort).joinToString("")
internal val allPriorities = priority.mapIndexed { index, char -> char to index }.toMap()
private val keyDistances: Map<Char, Object2IntMap<Char>> by lazy {
val keyDistanceMap = mutableMapOf<Char, Object2IntMap<Char>>()
val keyLocations = mutableMapOf<Char, Point2D>()
for ((rowIndex, rowChars) in rows.withIndex()) {
val keyY = rowIndex * 1.2F // Slightly increase cost of traveling between rows.
for ((columnIndex, char) in rowChars.withIndex()) {
val keyX = columnIndex + (0.25F * rowIndex) // Assume a 1/4-key uniform stagger.
keyLocations[char] = Point2D.Float(keyX, keyY)
}
}
for (fromChar in allChars) {
val distances = Object2IntOpenHashMap<Char>()
val fromLocation = keyLocations.getValue(fromChar)
for (toChar in allChars) {
distances[toChar] = floor(2F * fromLocation.distanceSq(keyLocations.getValue(toChar))).toInt()
}
keyDistanceMap[fromChar] = distances
}
keyDistanceMap
}
internal inline fun priority(crossinline tagToChar: (String) -> Char): (String) -> Int? {
return { allPriorities[tagToChar(it)] }
}
internal fun distanceBetweenKeys(char1: Char, char2: Char): Int {
return keyDistances.getValue(char1).getValue(char2)
}

View File

@ -1,9 +1,9 @@
package org.acejump.search
enum class Pattern(val regex: String) {
LINE_STARTS("^.|^\\n"),
LINE_STARTS("^.|^\\n|(?<!.)\\Z"),
LINE_ENDS("\\n|\\Z"),
LINE_INDENTS("[^\\s].*|^\\n"),
LINE_ALL_MARKS(LINE_ENDS.regex + "|" + LINE_STARTS.regex + "|" + LINE_INDENTS.regex),
LINE_INDENTS("[^\\s].*|^\\n|(?<!.)\\Z"),
LINE_ALL_MARKS(listOf(LINE_ENDS, LINE_STARTS, LINE_INDENTS).flatMap { it.regex.split("|") }.distinct().joinToString("|")),
ALL_WORDS("(?<=[^a-zA-Z0-9_]|\\A)[a-zA-Z0-9_]");
}

View File

@ -70,7 +70,7 @@ internal class SearchProcessor private constructor(
*/
fun type(char: Char, tagger: Tagger): Boolean {
val newQuery = query.rawText + char
val canMatchTag = tagger.canQueryMatchAnyTag(newQuery)
val canMatchTag = tagger.canQueryMatchAnyVisibleTag(newQuery)
// If the typed character is not compatible with any existing tag or as
// a continuation of any previous occurrence, reject the query change

View File

@ -51,7 +51,7 @@ internal sealed class SearchQuery {
class RegularExpression(private var pattern: String): SearchQuery() {
override val rawText = ""
override fun getHighlightLength(text: CharSequence, offset: Int) = 1
override fun getHighlightLength(text: CharSequence, offset: Int) = 0
override fun toRegex(): Regex =
Regex(pattern, setOf(RegexOption.MULTILINE, RegexOption.IGNORE_CASE))

View File

@ -187,7 +187,10 @@ internal class Solver private constructor(
val chars = editor.immutableText
val left = max(0, site + queryLength - 1)
val right = chars.wordEndPlus(site)
if (right >= chars.length) {
return
}
val builder = StringBuilder(1 + right - left)
for (i in left..right) {

View File

@ -5,13 +5,10 @@ import com.google.common.collect.HashBiMap
import com.intellij.openapi.editor.Editor
import it.unimi.dsi.fastutil.ints.IntArrayList
import it.unimi.dsi.fastutil.ints.IntList
import org.acejump.ExternalUsage
import org.acejump.*
import org.acejump.boundaries.EditorOffsetCache
import org.acejump.boundaries.StandardBoundaries.VISIBLE_ON_SCREEN
import org.acejump.immutableText
import org.acejump.input.KeyLayoutCache.allPossibleTags
import org.acejump.isWordPart
import org.acejump.matchesAt
import org.acejump.view.TagMarker
import java.util.AbstractMap.SimpleImmutableEntry
import kotlin.collections.component1
@ -143,24 +140,23 @@ internal class Tagger(private val editors: List<Editor>) {
}
}
private infix fun Map.Entry<String, Tag>.solves(query: String): Boolean {
return query.endsWith(key, true) && isTagCompatibleWithQuery(key, value, query)
}
private infix fun Map.Entry<String, Tag>.solves(query: String): Boolean =
query.endsWith(key, true) && isTagCompatibleWithQuery(key, value, query)
private fun isTagCompatibleWithQuery(marker: String, tag: Tag, query: String): Boolean {
return tag.editor.immutableText.matchesAt(tag.offset, getPlaintextPortion(query, marker), ignoreCase = true)
}
private fun isTagCompatibleWithQuery(marker: String, tag: Tag, query: String): Boolean =
tag.editor.immutableText.matchesAt(tag.offset, getPlaintextPortion(query, marker), ignoreCase = true)
fun isQueryCompatibleWithTagAt(query: String, tag: Tag): Boolean {
return tagMap.inverse()[tag].let { it != null && isTagCompatibleWithQuery(it, tag, query) }
}
fun isQueryCompatibleWithTagAt(query: String, tag: Tag): Boolean =
tagMap.inverse()[tag].let { it != null && isTagCompatibleWithQuery(it, tag, query) }
fun canQueryMatchAnyTag(query: String): Boolean {
return tagMap.any { (tag, offset) ->
val tagPortion = getTagPortion(query, tag)
tagPortion.isNotEmpty() && tag.startsWith(tagPortion, ignoreCase = true) && isTagCompatibleWithQuery(tag, offset, query)
fun canQueryMatchAnyVisibleTag(query: String): Boolean =
tagMap.any { (label, tag) ->
val tagPortion = getTagPortion(query, label)
tagPortion.isNotEmpty()
&& label.startsWith(tagPortion, ignoreCase = true)
&& isTagCompatibleWithQuery(label, tag, query)
&& tag.offset in tag.editor.getView()
}
}
private fun removeResultsWithOverlappingTags(editor: Editor, offsets: IntList) {
val iter = offsets.iterator()

View File

@ -10,7 +10,6 @@ import com.intellij.openapi.editor.Editor
internal data class EditorSettings(
private val isBlockCursor: Boolean,
private val isBlinkCaret: Boolean,
private val isReadOnly: Boolean
) {
companion object {
fun setup(editor: Editor): EditorSettings {
@ -20,12 +19,10 @@ internal data class EditorSettings(
val original = EditorSettings(
isBlockCursor = settings.isBlockCursor,
isBlinkCaret = settings.isBlinkCaret,
isReadOnly = !document.isWritable
)
settings.isBlockCursor = true
settings.isBlinkCaret = false
document.setReadOnly(true)
return original
}
@ -37,6 +34,5 @@ internal data class EditorSettings(
settings.isBlockCursor = isBlockCursor
settings.isBlinkCaret = isBlinkCaret
document.setReadOnly(isReadOnly)
}
}

View File

@ -81,6 +81,10 @@ class TagMarker(
g.color = AceConfig.tagForegroundColor
g.drawString(text, x, y)
}
private fun isLineEnding(char: Char): Boolean {
return char == '\n' || char == '\r'
}
}
/**
@ -106,7 +110,7 @@ class TagMarker(
private fun alignTag(editor: Editor, cache: EditorOffsetCache, font: TagFont, occupied: List<Rectangle>): Rectangle? {
val boundaries = VISIBLE_ON_SCREEN
if (hasSpaceRight || offsetL == 0 || editor.immutableText[offsetL - 1].let { it == '\n' || it == '\r' }) {
if (hasSpaceRight || offsetL !in 1 until editor.document.textLength || isLineEnding(editor.immutableText[offsetL - 1])) {
val rectR = createRightAlignedTagRect(editor, cache, font)
return rectR.takeIf { boundaries.isOffsetInside(editor, offsetR, cache) && occupied.none(rectR::intersects) }
}
@ -124,7 +128,15 @@ class TagMarker(
private fun createRightAlignedTagRect(editor: Editor, cache: EditorOffsetCache, font: TagFont): Rectangle {
val pos = cache.offsetToXY(editor, offsetR)
val shift = font.editorFontMetrics.charWidth(editor.immutableText[offsetR]) + (font.tagCharWidth * shiftR)
val char = if (offsetR >= editor.document.textLength)
' ' // Use the width of a space on the last line.
else editor.immutableText[offsetR].let {
// Use the width of a space on empty lines.
if (isLineEnding(it)) ' ' else it
}
val shift = font.editorFontMetrics.charWidth(char) + (font.tagCharWidth * shiftR)
return Rectangle(pos.x + shift, pos.y, (font.tagCharWidth * length) + 4, font.lineHeight)
}

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.HighlighterTargetArea.EXACT_RANGE
import com.intellij.ui.*
import com.intellij.util.DocumentUtil
import com.intellij.util.ui.*
import it.unimi.dsi.fastutil.ints.IntList
import org.acejump.*
@ -31,7 +32,7 @@ internal class TextHighlighter {
/**
* Label for the search notification.
*/
private class NotificationLabel constructor(text: String?): JLabel(text) {
private class NotificationLabel(text: String?): JLabel(text) {
init {
background = HintUtil.getInformationColor()
foreground = JBColor.foreground()
@ -61,9 +62,7 @@ internal class TextHighlighter {
val modifications = (highlights?.size ?: 0) + offsets.size
val enableBulkEditing = modifications > 1000
try {
if (enableBulkEditing) document.isInBulkUpdate = true
DocumentUtil.executeInBulk(document, enableBulkEditing) {
highlights?.forEach(markup::removeHighlighter)
previousHighlights[editor] = Array(offsets.size) { index ->
val start = offsets.getInt(index)
@ -72,8 +71,6 @@ internal class TextHighlighter {
markup.addRangeHighlighter(start, end, LAYER, null, EXACT_RANGE)
.apply { customRenderer = renderer }
}
} finally {
if (enableBulkEditing) document.isInBulkUpdate = false
}
}
@ -96,58 +93,64 @@ internal class TextHighlighter {
previousHint?.hide()
// add notification hint to first editor
results.keys.first().let {
val component: JComponent = it.component
val editor = results.keys.first()
val component: JComponent = editor.component
val label1: JLabel = NotificationLabel(" " +
CodeInsightBundle.message("incremental.search.tooltip.prefix"))
label1.font = UIUtil.getLabelFont().deriveFont(Font.BOLD)
val label1 = NotificationLabel(
" " +
CodeInsightBundle.message("incremental.search.tooltip.prefix")
).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()
val label2 = NotificationLabel(queryText)
val queryText = " " +
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}" +
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 {
add(label1, BorderLayout.WEST)
add(label2, BorderLayout.CENTER)
add(label3, BorderLayout.EAST)
border = BorderFactory.createLineBorder(
if (jumpMode == JumpMode.DISABLED) JBColor.BLACK else jumpMode.caretColor
)
val panel = JPanel(BorderLayout()).apply {
add(label1, BorderLayout.WEST)
add(label2, BorderLayout.CENTER)
add(label3, BorderLayout.EAST)
border = BorderFactory.createLineBorder(
if (jumpMode == JumpMode.DISABLED) Color.BLACK else jumpMode.caretColor
)
preferredSize = Dimension(it.contentComponent.width +
label1.preferredSize.width, preferredSize.height)
}
val hint = LightweightHint(panel)
val x = SwingUtilities.convertPoint(component, 0, 0, component).x
val y: Int = -hint.component.preferredSize.height
val p = SwingUtilities.convertPoint(component, x, y,
component.rootPane.layeredPane)
HintManagerImpl.getInstanceImpl().showEditorHint(
hint,
it,
p,
HIDE_BY_ESCAPE or HIDE_BY_TEXT_CHANGE,
0,
false,
HintHint(it, p).setAwtTooltip(false)
preferredSize = Dimension(
editor.contentComponent.width +
label1.preferredSize.width, preferredSize.height
)
previousHint = hint
}
val hint = LightweightHint(panel)
val x = SwingUtilities.convertPoint(component, 0, 0, component).x
val y: Int = -hint.component.preferredSize.height
val p = SwingUtilities.convertPoint(
component, x, y,
component.rootPane.layeredPane
)
HintManagerImpl.getInstanceImpl().showEditorHint(
hint,
editor,
p,
HIDE_BY_ESCAPE or HIDE_BY_TEXT_CHANGE,
0,
false,
HintHint(editor, p).setAwtTooltip(false)
)
previousHint = hint
}
fun reset() {
previousHighlights.keys.forEach { it.markupModel.removeAllHighlighters() }
previousHighlights.forEach { (editor, highlighters) ->
highlighters.forEach(editor.markupModel::removeHighlighter)
}
previousHighlights.clear()
previousHint?.hide()
}

View File

@ -20,27 +20,38 @@
id="preferences.AceConfigurable" dynamic="true"/>
<editorActionHandler action="EditorEscape" order="first"
implementationClass="org.acejump.action.AceEditorAction$Reset"/>
implementationClass="org.acejump.action.AceEditorAction$Reset"
id="AceHandlerEscape"/>
<editorActionHandler action="EditorBackSpace" order="first"
implementationClass="org.acejump.action.AceEditorAction$ClearSearch"/>
implementationClass="org.acejump.action.AceEditorAction$ClearSearch"
id="AceHandlerBackSpace"/>
<editorActionHandler action="EditorStartNewLine" order="first"
implementationClass="org.acejump.action.AceEditorAction$SelectBackward"/>
implementationClass="org.acejump.action.AceEditorAction$SelectBackward"
id="AceHandlerStartNewLine"/>
<editorActionHandler action="EditorEnter" order="first"
implementationClass="org.acejump.action.AceEditorAction$SelectForward"/>
implementationClass="org.acejump.action.AceEditorAction$SelectForward"
id="AceHandlerEnter"/>
<editorActionHandler action="EditorTab" order="first"
implementationClass="org.acejump.action.AceEditorAction$ScrollToNextScreenful"/>
implementationClass="org.acejump.action.AceEditorAction$ScrollToNextScreenful"
id="AceHandlerTab"/>
<editorActionHandler action="EditorUnindentSelection" order="first"
implementationClass="org.acejump.action.AceEditorAction$ScrollToPreviousScreenful"/>
implementationClass="org.acejump.action.AceEditorAction$ScrollToPreviousScreenful"
id="AceHandlerUnindentSelection"/>
<editorActionHandler action="EditorUp" order="first"
implementationClass="org.acejump.action.AceEditorAction$SearchLineStarts"/>
implementationClass="org.acejump.action.AceEditorAction$SearchLineStarts"
id="AceHandlerUp"/>
<editorActionHandler action="EditorLeft" order="first"
implementationClass="org.acejump.action.AceEditorAction$SearchLineIndents"/>
implementationClass="org.acejump.action.AceEditorAction$SearchLineIndents"
id="AceHandlerLeft"/>
<editorActionHandler action="EditorLineStart" order="first"
implementationClass="org.acejump.action.AceEditorAction$SearchLineIndents"/>
implementationClass="org.acejump.action.AceEditorAction$SearchLineIndents"
id="AceHandlerLineStart"/>
<editorActionHandler action="EditorRight" order="first"
implementationClass="org.acejump.action.AceEditorAction$SearchLineEnds"/>
implementationClass="org.acejump.action.AceEditorAction$SearchLineEnds"
id="AceHandlerRight"/>
<editorActionHandler action="EditorLineEnd" order="first"
implementationClass="org.acejump.action.AceEditorAction$SearchLineEnds"/>
implementationClass="org.acejump.action.AceEditorAction$SearchLineEnds"
id="AceHandlerLineEnd"/>
</extensions>
@ -55,6 +66,12 @@
<action id="AceReverseAction"
class="org.acejump.action.AceAction$ActivateOrReverseCycleMode"
text="Activate / Reverse Cycle AceJump Mode"/>
<action id="AceForwardAction"
class="org.acejump.action.AceAction$ToggleForwardJumpMode"
text="Start AceJump in Jump After Caret Mode"/>
<action id="AceBackwardAction"
class="org.acejump.action.AceAction$ToggleBackwardJumpMode"
text="Start AceJump in Jump Before Caret Mode"/>
<action id="AceWordStartAction"
class="org.acejump.action.AceAction$ToggleJumpMode"
text="Start AceJump in Jump Mode"/>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 40 41" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<svg width="100%" height="100%" viewBox="0 0 40 41" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,0,-635)">
<g id="pluginIcon" transform="matrix(0.154082,0,0,0.154082,-39.7746,553.645)">
<rect x="258.139" y="529.264" width="259.602" height="259.602" style="fill:none;"/>

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -121,11 +121,11 @@ class AceTest : BaseTest() {
}
fun `test line mode`() {
makeEditor(" test\n three\n lines\n")
makeEditor(" test\n three\n lines")
takeAction(AceAction.StartAllLineMarksMode())
assertEquals(8, session.tags.size) // last empty line does not count
assertEquals(9, session.tags.size)
}
fun `test chinese selection`() {

View File

@ -1,5 +1,7 @@
import com.intellij.mock.MockVirtualFile
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.markup.HighlighterLayer
import com.intellij.openapi.editor.markup.HighlighterTargetArea
import com.intellij.openapi.fileEditor.TextEditor
import com.intellij.util.ui.UIUtil
import it.unimi.dsi.fastutil.ints.IntArrayList
@ -41,12 +43,12 @@ class ExternalUsageTest: BaseTest() {
fun `test externally tagged results with multiple editors`() {
val fileA = MockVirtualFile("a.txt", "first file")
val fileB = MockVirtualFile("b.txt", "second file with more markers")
myManager.openFile(fileA, true)
myManager.openFile(fileB, false)
manager?.openFile(fileA, true)
manager?.openFile(fileB, false)
val mainEditor = (myManager.selectedEditor as TextEditor).editor
val editorA = (myManager.getEditors(fileA).single() as TextEditor).editor
val editorB = (myManager.getEditors(fileB).single() as TextEditor).editor
val mainEditor = (manager?.selectedEditor as TextEditor).editor
val editorA = (manager?.getEditors(fileA)?.single() as TextEditor).editor
val editorB = (manager?.getEditors(fileB)?.single() as TextEditor).editor
val session = SessionManager.start(mainEditor, listOf(editorA, editorB))
@ -85,7 +87,7 @@ class ExternalUsageTest: BaseTest() {
SessionManager.start(myFixture.editor)
.startRegexSearch("[aeiou]+", WHOLE_FILE)
TestCase.assertEquals(8, session.tags.size)
TestCase.assertEquals(9, session.tags.size)
}
fun `test external jump with bounds`() {
@ -166,4 +168,21 @@ class ExternalUsageTest: BaseTest() {
TestCase.assertEquals(mark, detectedMark)
TestCase.assertEquals("", detectedQuery)
}
fun `test do not remove other highlights when the session ends`() {
makeEditor("test do not remove other highlights when the session ends")
val markupModel = myFixture.editor.markupModel
val layer = HighlighterLayer.SELECTION - 1
val existedHighlighter = markupModel.addRangeHighlighter(0, 1, layer, null, HighlighterTargetArea.EXACT_RANGE)
takeAction(AceAction.StartAllWordsMode())
val mark = session.tags[0].key
typeAndWaitForResults(mark)
TestCase.assertEquals("last session should be disposed", null, SessionManager[myFixture.editor])
TestCase.assertTrue("existed highlighter should not be removed", existedHighlighter.isValid)
existedHighlighter.dispose()
}
}

View File

@ -7,7 +7,6 @@ import kotlin.system.measureTimeMillis
@Ignore
class LatencyTest: BaseTest() {
private fun `test tag latency`(editorText: String) {
val chars = editorText.toCharArray().distinct().filter { !it.isWhitespace() }
val avg = averageTimeWithWarmup(warmupRuns = 10, timedRuns = 10) {

View File

@ -38,7 +38,7 @@ abstract class BaseTest: FileEditorManagerTestCase() {
UIUtil.dispatchAllInvocationEvents()
assertEmpty(it.markupModel.allHighlighters)
}
myManager.closeAllFiles()
manager?.closeAllFiles()
}
fun typeAndWaitForResults(string: String) {