Code Monkey home page Code Monkey logo

limited-wip's Introduction

Build Status

Limited WIP

This is a plugin for IntelliJ IDEs to limit work-in-progress (WIP) by adding constraints to your normal workflow in IDE.

It has three main components (each one can be enabled/disabled):

  • Change size watchdog: shows notifications when current changelist size exceeds threshold
  • Auto-revert: automatically reverts current changelist after a timeout (the timer is reset after each commit)
  • TCR mode (test && commit || revert): you can only commit after running a test; if the test fails, current changelist is reverted; if the test passes, changes are automatically committed

Why?

  • focus on one thing at a time, make really small steps and commit as soon as you're done
  • practice various constraints as if you're at a code retreat
  • explore your limits and learn new refactoring, coding and problem solving techniques

Change size watchdog

Whenever size of the current change list exceeds specified threshold, watchdog will show notification popup reminding to reduce amount of changes. This is the least extreme constraint and has been used on large scale enterprise projects.

You can find settings in Preferences -> Other Settings -> Limited WIP, where you can:

  • enable/disable component
  • change size threshold which is measured as the amount of lines changed ignoring empty lines (if file was deleted, then the amount of lines in the file). There are no particular reasons for the predefined thresholds of 40, 80, 100, 120. These numbers are just a guess.
  • notification interval, i.e. how often watchdog will nag you after exceeding threshold
  • enable/disable statusbar widget showing current change size and change size threshold, e.g. Change size: 50/80 means that change size is 50 and threshold is 80. You can click on the widget to suppress notifications until next commit.
  • enable/disable commits after change size exceeded threshold. If enabled and change size is above threshold, you will not be able to open commit dialog and will see notification popup instead (although you can still force commit by clicking on the link in the popup).
  • choose excluded files which will not be monitored by the watchdog. Use ; to separate patterns. Accepted wildcards: ? - exactly one symbol; * - zero or more symbols; / - path separator; /**/ - any number of directories.

Auto-revert

  • Timer starts as soon as there are any changes in version control.
  • Timer resets when there are no more changes (because of commit, revert or undo).
  • When timer reaches 0 seconds, all changes are automatically reverted.

This constraint has been used at code retreats with 5 minute timeout for quite a few years. It has been useful on large scale enterprise projects with longer timeouts (e.g. 30, 60, 120 minutes). And it also seems to work well in combination with TCR.

You can find settings in Preferences -> Other Settings -> Limited WIP, where you can:

  • enable/disable component (it is disabled by default)
  • timeout until revert in minutes or seconds
  • enable/disable notification on auto-revert (to make it clear why current changes disappeared)
  • enable/disable displaying timer in auto-revert widget. Sometimes it can be useful to see how much time is left till revert. In other cases, you might prefer not to see time left and just focus on making the smallest change possible.

This is not part of the workflow, but you can pause the timer by clicking on auto-revert widget in IDE toolbar.

TCR mode (test && commit || revert)

  • You're not allowed to commit without running a test.
  • If the test fails, current change list is reverted.
  • If the test passed, changes are committed.

This is the most recent constraint so there isn't a lot of experience using it. However, it's much more useful and enjoyable than it might seem initially.

You can find settings in Preferences -> Other Settings -> Limited WIP, where you can:

  • enable/disable component (disabled by default)
  • choose action on passed test, it can be
    • commit
    • amend commit (will open commit dialog if the last commit has been pushed or different set of tests has been run compared to last execution)
    • commit and push (if "push" is supported by VCS)
    • open commit dialog
  • choose commit message source, it can be
    • last commit
    • current changelist name
  • enable/disable notification on revert (to make it clear why current changes disappeared)
  • enable/disable revert of test code (aka relaxed TCR)
  • exclude files from revert in case some tests are not marked as test source root in IDE

I heard about the idea from Kent Beck mentioning Limbo and his "test && commit || revert" blog post in particular. Originally, the idea comes from Oddmund Strømme, Lars Barlindhaug and Ole Tjensvoll Johannessen.

Screenshots

settings screenshot


change limit exceeded notification


commit cancelled notification


Videos

History

The original version of the plugin called "Auto-revert" was conceived at LSCC meetup in 2012 after having a chat with Samir Talwar (it's easy to implement a basic version of auto-revert in bash but there are problems like resetting the timer after each commit and that IntelliJ will be asking on each revert from terminal if you really want to load changes from file system).

Some time later (in 2015) after using auto-revert for a while on large legacy code bases, I found that it can be too harsh sometimes, especially when you're in exploration mode. To solve the problem watchdog component was created which doesn't revert but just notifies if there are too many changes.

At FFS tech conf 2018 Kent Beck mentioned Limbo and test && commit || revert which looked like a great fit for the plugin so I had to implement it.

I hope there will be more components in the future. If you have an idea, feel free to create github issue or tweet it to me.

limited-wip's People

Contributors

dkandalov avatar jpbelang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

limited-wip's Issues

Remember files selected for commit when forcing commit

  • modify several files which are overall above change threshold (or use TCR mode)
  • select one of the files and attempt to commit
  • plugin will cancel the commit
  • click on the popup to force commit anyway
  • in the commit dialog all files are selected for commit rather than just one file which was originally selected

Manual undo operation does not work properly after failing test

Software versions:

  • PyCharm 2021.3.2 CE
  • Limited WIP 0.3.13

Settings:

  • Change Size Watchdog: disabled
  • Auto-Revert: disabled
  • TCR: enabled
    • don't revert test: enabled
    • don't revert files: **

Steps to reproduce:

  • make a change that breaks the tests
  • run tests
  • press undo key shortcut

Actual result

"Undo reload from Disk" dialog pops up. After clicking on "close" the change is not undone. An additional undo press is needed to really perform the undo.

Expected result

The undo should be performed on first shortcut press without the "Undo reload from Disk" dialog popping up.

Auto-Revert: Don't start the timer until there is a change

Hi @dkandalov!
First of all thank you for this great tool. Good job!

I really appreciate the auto-revert but the problem is that the timer starts immediately after the commit / revert. I would love it to only start when I start coding again. Otherwise, I could commit, go read some documentation, come back to write something an I would only have 10 seconds or something :). You can check that out here: https://www.youtube.com/watch?v=4a98KvVJFRw

What would you think about waiting for currentChangeListSizeInLines to be non-empty in auto-revert before starting the timer.

Instead of reseting the counter if there's a revert, it would be reset every time there are no more changes ( commit / revert / undo...).

Thank you!

should not update shared misc.xml

misc.xml is intended to have non-developer specific settings in it, i.e. settings that should be shared. As such, it's inappropriate for settings from the Limited WIP plugin to be putting settings in that file. It'd be best if an appropriate non-shared file was used. It was my understanding that the entire .idea directory should be shared, and that only workspaces.xml was not supposed to be, so perhaps put it in there? That's a user specific setup

https://intellij-support.jetbrains.com/hc/en-us/community/posts/360005054360-Get-misc-xml-from-VCS-but-do-not-track-it-by-default

Anyhow, it's cause my LimitedWIP settings to flap back and forth depending on what happens with my git repo.

AlreadyDisposedException: Cannot create com.intellij.openapi.vcs.ProjectLevelVcsManager

com.intellij.serviceContainer.AlreadyDisposedException: Cannot create com.intellij.openapi.vcs.ProjectLevelVcsManager because container is already disposed (container=Project(name=coins, containerState=DISPOSE_COMPLETED, componentStore=/Users/dima/IdeaProjects/coins) (disposed))
	at com.intellij.serviceContainer.ContainerUtilKt.throwAlreadyDisposedError(containerUtil.kt:43)
	at com.intellij.serviceContainer.ComponentManagerImpl.doGetService(ComponentManagerImpl.kt:612)
	at com.intellij.serviceContainer.ComponentManagerImpl.getService(ComponentManagerImpl.kt:573)
	at com.intellij.openapi.client.ClientAwareComponentManager.getFromSelfOrCurrentSession(ClientAwareComponentManager.kt:37)
	at com.intellij.openapi.client.ClientAwareComponentManager.getService(ClientAwareComponentManager.kt:22)
	at com.intellij.openapi.vcs.ProjectLevelVcsManager.getInstance(ProjectLevelVcsManager.java:37)
	at com.intellij.openapi.vcs.impl.ContentRevisionCache.getOrLoadAsBytes(ContentRevisionCache.java:172)
	at git4idea.GitContentRevision.getContentAsBytes(GitContentRevision.java:66)
	at git4idea.GitContentRevision.getContent(GitContentRevision.java:55)
	at limitedwip.watchdog.components.ChangeSizeWatcherKt.doCalculateChangeSizeInLines(ChangeSizeWatcher.kt:135)
	at limitedwip.watchdog.components.ChangeSizeWatcherKt.calculateChangeSizeInLines(ChangeSizeWatcher.kt:116)
	at limitedwip.watchdog.components.ChangeSizeWatcher$calculateCurrentChangeListSizeInLines$2.run(ChangeSizeWatcher.kt:68)
	at com.intellij.openapi.application.impl.ApplicationImpl$1.run(ApplicationImpl.java:265)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:668)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:665)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:665)
	at java.base/java.lang.Thread.run(Thread.java:829)

Add a "I'm being disturbed" button to stop the timer.

At work, I'm interrupted with some frequency and I'd rather not have to artificially bump up the time
of my auto-revert. Having this button could help avoid doing this.

Maybe a popup when you click on the countdown ?

Have I told you how much I'm enjoying this plugin ? :-)

Exception Already disposed: Project (Disposed)

This happens form time to time.
As a side-effect the counter in the task bar at the bottom will always show "Change Size: 0/80" even when there are changes.
The bubble warning about too many changes appears correctly, so this is not affected.

Note: the project mentioned in the stack trace (openwebstart-parent) is not the one I was working on when the exception occurred. I worked on that project earlier that day. Then I switched workspace to a different project.
I switch between projects by opening the new one in a new window and then later closing the old window.

My OS is linux. Intellij and all plugins are on the latest version.

java.lang.AssertionError: Already disposed: Project (Disposed) openwebstart-parent
	at com.intellij.openapi.components.impl.ComponentManagerImpl.lambda$throwAlreadyDisposed$1(ComponentManagerImpl.java:286)
	at com.intellij.openapi.application.ReadAction.lambda$run$1(ReadAction.java:53)
	at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:932)
	at com.intellij.openapi.application.ReadAction.compute(ReadAction.java:57)
	at com.intellij.openapi.application.ReadAction.run(ReadAction.java:53)
	at com.intellij.openapi.components.impl.ComponentManagerImpl.throwAlreadyDisposed(ComponentManagerImpl.java:284)
	at com.intellij.openapi.components.impl.ComponentManagerImpl.getMessageBus(ComponentManagerImpl.java:152)
	at limitedwip.watchdog.components.Ide.showNotificationThatWatchdogIsDisableUntilNextCommit(Ide.kt:63)
	at limitedwip.watchdog.Watchdog.skipNotificationsUntilCommit(Watchdog.kt:83)
	at limitedwip.watchdog.Watchdog.toggleSkipNotificationsUntilCommit(Watchdog.kt:63)
	at limitedwip.watchdog.components.WatchdogComponent$start$1.onWidgetClick(WatchdogComponent.kt:32)
	at limitedwip.watchdog.components.Ide$1.onClick(Ide.kt:30)
	at limitedwip.watchdog.ui.WatchdogStatusBarWidget$getPresentation$1$getClickConsumer$1.consume(WatchdogStatusBarWidget.kt:31)
	at limitedwip.watchdog.ui.WatchdogStatusBarWidget$getPresentation$1$getClickConsumer$1.consume(WatchdogStatusBarWidget.kt:28)
	at com.intellij.openapi.wm.impl.status.IdeStatusBarImpl$TextPresentationWrapper$1.mousePressed(IdeStatusBarImpl.java:692)
	at java.desktop/java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:287)
	at java.desktop/java.awt.Component.processMouseEvent(Component.java:6648)
	at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
	at java.desktop/java.awt.Component.processEvent(Component.java:6416)
	at java.desktop/java.awt.Container.processEvent(Container.java:2263)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5026)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4858)
	at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
	at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4544)
	at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
	at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2773)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4858)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:778)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:751)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:749)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:748)
	at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:824)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:769)
	at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:412)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:704)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:411)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

should the TCR mode automatically commit after I run a test? It doesn't seem to be committing.

Hi Dmitry,

Thanks for your work on this plugin.

I can't tell if I've set up the plugin wrong (in which case I am offering to submit a PR to clarify the README) or of the plugin doesn't auto-commit (in which case this is a feature request).

What I was expecting from the plugin was a way to auto-commit after running a test. In the TCR workflow that I've seen described, the tests run automatically when you save and the tool either commits or reverts automatically depending on the results of the test. I assumed that the Limited Wip plugging uses the test run as the trigger instead of the file save. I thought that after I manually run a test (which passes) that Limited Wip would add all the files in my workspace to git and then make a commit. (And if the test had failed, then all those changes would be blown away and new files would be deleted.)

However, after enabling TCR mode (and disabling the other two), I find that I have uncommited changes even after running tests. I thought perhaps Limited Wip wasn't adding the files to git, so I tried manually adding the files (git add -A) and then rerunning the test. I still have my uncommited changes in my workspace.

Have I misunderstood how Limited Wip works? Or Is it not doing what it's supposed to?

Cheers,
Alex

screenshot of my config which has TCR mode enabled and On Passed Test set to "commit"

Feature Request: support timeout period less than 1 minute

Hi there,

Great stuff first of all.

Right now '1 Minute' is the minimum timeout period. Possible for us to set it to like '30 seconds', '15 seconds', '45 seconds'(this three looks sufficient to me)? This is useful when we're doing a Refactor/TDD workshop to enforce people to run tests frequently, or should be something also useful for experienced developer that would like to push themselves to the limits.

image

Feel free to let me know your thoughts, concerns anything.

Plugin settings UI is not searchable

  • open `IDE settings -> Limited WIP
  • type "revert" in search dialog
  • matching UI elements are highlighted while typing, however, half second later Limited WIP settings disappear from the list of matching settings

Argument for @NotNull parameter 'commitMessage' must not be null

To reproduce:

  • create new project, init git
  • run Quick commit command (which will attempt by default to use message from the last commit)
java.lang.IllegalArgumentException: Argument for @NotNull parameter 'commitMessage' of com/intellij/openapi/vcs/changes/ui/CommitHelper.<init> must not be null
        at com.intellij.openapi.vcs.changes.ui.CommitHelper.$$$reportNull$$$0(CommitHelper.java)
        at com.intellij.openapi.vcs.changes.ui.CommitHelper.<init>(CommitHelper.java)
        at limitedwip.autorevert.ui.QuickCommitAction$actionPerformed$runnable$1.run(QuickCommitAction.kt:50)
        at com.intellij.openapi.vcs.changes.Waiter.onSuccess(Waiter.java:52)
        at com.intellij.openapi.progress.impl.CoreProgressManager.finishTask(CoreProgressManager.java:502)
        at com.intellij.openapi.progress.impl.CoreProgressManager.runProcessWithProgressSynchronously(CoreProgressManager.java:457)
        at com.intellij.openapi.progress.impl.ProgressManagerImpl.runProcessWithProgressSynchronously(ProgressManagerImpl.java:109)
        at com.intellij.openapi.progress.impl.CoreProgressManager.runSynchronously(CoreProgressManager.java:319)
        at com.intellij.openapi.progress.impl.CoreProgressManager.run(CoreProgressManager.java:304)
        at com.intellij.openapi.vcs.changes.CallbackData.lambda$createInteractive$3(CallbackData.java:85)
        at com.intellij.openapi.vcs.changes.UpdateRequestsQueue.invokeAfterUpdate(UpdateRequestsQueue.java:182)
        at com.intellij.openapi.vcs.changes.ChangeListManagerImpl.invokeAfterUpdate(ChangeListManagerImpl.java:417)
        at com.intellij.openapi.vcs.changes.ChangeListManagerImpl.invokeAfterUpdate(ChangeListManagerImpl.java:405)
        at limitedwip.autorevert.ui.QuickCommitAction.actionPerformed(QuickCommitAction.kt:63)
        at limitedwip.common.vcs.Commit_and_pushKt$doQuickCommit$1.invoke(commit-and-push.kt:29)
        at limitedwip.common.vcs.Commit_and_pushKt$doQuickCommit$1.invoke(commit-and-push.kt)
        at limitedwip.common.vcs.Commit_and_pushKt$sam$Runnable$18109781.run(commit-and-push.kt)
        at com.intellij.openapi.application.TransactionGuardImpl$2.run(TransactionGuardImpl.java:315)
        at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.doRun(LaterInvocator.java:435)
        at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.runNextEvent(LaterInvocator.java:419)
        at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.run(LaterInvocator.java:403)
        at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
        at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
        at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
        at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
        at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:729)
        at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:678)
        at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:373)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)

Commits are still allowed even if you go over watchdog threshold

Build #IU-203.6682.168, built on December 29, 2020
Runtime version: 11.0.9.1+11-b944.50 x86_64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.

But the same version of LimitedWIP plugin (0.3.12) works fine in the latest version of IJ so it might a bug IJ. So I won't try to make the plugin work in 203.6682.168 unless someone really needs this.

LineFragment.checkChildren Assertion failed

Happens even with change size watch and revert disabled.
IU-139.658.4 seems to occur with any .xml changes in default change list:

Assertion failed
java.lang.Throwable
    at com.intellij.openapi.diagnostic.Logger.assertTrue(Logger.java:144)
    at com.intellij.openapi.diagnostic.Logger.assertTrue(Logger.java:153)
    at com.intellij.openapi.diff.impl.fragments.LineFragment.checkChildren(LineFragment.java:199)
    at com.intellij.openapi.diff.impl.fragments.LineFragment.setChildren(LineFragment.java:182)
    at com.intellij.openapi.diff.impl.processing.TextCompareProcessor.process(TextCompareProcessor.java:80)
    at limitedwip.components.VcsIdeUtil.amountOfChangedLinesIn(VcsIdeUtil.java:63)
    at limitedwip.components.VcsIdeUtil.currentChangeListSizeInLines(VcsIdeUtil.java:40)
    at limitedwip.IdeActions$1.compute(IdeActions.java:47)
    at limitedwip.IdeActions$1.compute(IdeActions.java:44)
    at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:928)
    at limitedwip.IdeActions.currentChangeListSizeInLines(IdeActions.java:44)
    at limitedwip.components.LimitedWIPProjectComponent$1.onTimerUpdate(LimitedWIPProjectComponent.java:66)
    at limitedwip.components.TimerEventsSource$1.run(TimerEventsSource.java:40)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)

Commit without dialog action doesn't work in 2019.3 EAP

IntelliJ IDEA 2019.3 EAP (Ultimate Edition)
Build #IU-193.4099.13, built on October 2, 2019

java.lang.NoSuchMethodError: com.intellij.vcs.commit.SingleChangeListCommitter.<init>(Lcom/intellij/openapi/project/Project;Lcom/intellij/vcs/commit/ChangeListCommitState;Lcom/intellij/openapi/vcs/changes/CommitContext;Ljava/util/List;Lcom/intellij/openapi/vcs/AbstractVcs;Ljava/lang/String;Z)V
	at limitedwip.common.vcs.CommitHelper.<init>(commit-without-dialog.kt:153)
	at limitedwip.common.vcs.Commit_without_dialogKt$doCommitWithoutDialog$runnable$1.run(commit-without-dialog.kt:66)
	at com.intellij.openapi.vcs.changes.Waiter.onSuccess(Waiter.java:52)
	at com.intellij.openapi.progress.impl.CoreProgressManager.finishTask(CoreProgressManager.java:501)
	at com.intellij.openapi.progress.impl.CoreProgressManager.runProcessWithProgressSynchronously(CoreProgressManager.java:456)
	at com.intellij.openapi.progress.impl.ProgressManagerImpl.runProcessWithProgressSynchronously(ProgressManagerImpl.java:82)
	at com.intellij.openapi.progress.impl.CoreProgressManager.runSynchronously(CoreProgressManager.java:318)
	at com.intellij.openapi.progress.impl.CoreProgressManager.run(CoreProgressManager.java:303)
	at com.intellij.openapi.vcs.changes.CallbackData.lambda$createInteractive$3(CallbackData.java:85)
	at com.intellij.openapi.vcs.changes.UpdateRequestsQueue.invokeAfterUpdate(UpdateRequestsQueue.java:180)
	at com.intellij.openapi.vcs.changes.ChangeListManagerImpl.invokeAfterUpdate(ChangeListManagerImpl.java:372)
	at com.intellij.openapi.vcs.changes.ChangeListManagerImpl.invokeAfterUpdate(ChangeListManagerImpl.java:360)
	at limitedwip.common.vcs.Commit_without_dialogKt.doCommitWithoutDialog(commit-without-dialog.kt:81)
	at limitedwip.common.vcs.Commit_without_dialogKt.doCommitWithoutDialog$default(commit-without-dialog.kt:35)
	at limitedwip.common.vcs.CommitWithoutDialogAction.actionPerformed(commit-without-dialog.kt:31)
	at com.intellij.openapi.actionSystem.ex.ActionUtil$1.run(ActionUtil.java:266)
	at com.intellij.openapi.actionSystem.ex.ActionUtil.performActionDumbAware(ActionUtil.java:283)
	at com.intellij.ide.actions.GotoActionAction.lambda$performAction$7(GotoActionAction.java:335)
	at com.intellij.openapi.application.TransactionGuardImpl.runSyncTransaction(TransactionGuardImpl.java:83)
	at com.intellij.openapi.application.TransactionGuardImpl.lambda$submitTransaction$1(TransactionGuardImpl.java:107)
	at com.intellij.openapi.application.TransactionGuardImpl.submitTransaction(TransactionGuardImpl.java:116)
	at com.intellij.openapi.application.TransactionGuardImpl.lambda$submitTransactionLater$4(TransactionGuardImpl.java:265)
	at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.doRun(LaterInvocator.java:441)
	at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.runNextEvent(LaterInvocator.java:424)
	at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.run(LaterInvocator.java:407)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:762)
	at java.awt.EventQueue.access$500(EventQueue.java:98)
	at java.awt.EventQueue$3.run(EventQueue.java:715)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:732)
	at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:906)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:779)
	at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:422)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:698)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:421)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Stop time if commit dialog is open

Scenario:

Using the clock as the constraint.

editing -> finished work -> open commit dialog one second before the time runs out - add 2 seconds -> limitWip reverts -> change lost

Improvement:

Stop the clock. (not reset) Continue the clock if the dialog closes without commit

Behaviour when VCS roots are removed from the project

For example:

  • watchdog shows a change size of 65/80
  • remove all VCS from the project settings
  • watchdog still shows change size of 65/80 and keeps tracking changes (there is probably a similar issue with other modules)

TCR without revert

I would like to work in 'soft' TCR mode, committing on successful tests but without the automatic revert on test failure.

A simple setting for this mode would be very useful. I can set a 'don't revert' file matcher to '**', but deleted files are still reverted. Maybe a combo-box similar to the one for 'On passed test' with options "revert all", "revert production only", "do nothing"?

Two commit dialogs open when tests run with Gradle run configuration

In a Gradle project, when tests are run with the Gradle run configuration (this is set up by default by IntelliJ when e.g. doing control-shift-R on a module) two identical "Commit Changes" dialogs open on a passed test, one on top of the other. If a JUnit run configuration is set up manually (and this is the default in a Maven project), the commit dialog appears once, as expected.

Write access is allowed from write-safe contexts only.

I ran into an error. I let the time get to 5 minutes to do a revert. The code disappeared and then PHP Storm popped up an error. I'm including it below.

Error:
Write access is allowed from write-safe contexts only. Please ensure you're using invokeLater/invokeAndWait with a correct modality state (not "any"). See TransactionGuard documentation for details.

Details:

Write access is allowed from write-safe contexts only. Please ensure you're using invokeLater/invokeAndWait with a correct modality state (not "any"). See TransactionGuard documentation for details.
  current modality=ModalityState.NON_MODAL
  known modalities={ModalityState.NON_MODAL=true, ModalityState.NON_MODAL=true}
java.lang.Throwable
	at com.intellij.openapi.diagnostic.Logger.error(Logger.java:132)
	at com.intellij.openapi.application.TransactionGuardImpl.assertWriteActionAllowed(TransactionGuardImpl.java:246)
	at com.intellij.openapi.editor.impl.DocumentImpl.c(DocumentImpl.java:619)
	at com.intellij.openapi.editor.impl.DocumentImpl.a(DocumentImpl.java:548)
	at com.intellij.openapi.editor.impl.DocumentImpl.replaceText(DocumentImpl.java:455)
	at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl$2.run(FileDocumentManagerImpl.java:634)
	at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:934)
	at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.a(FileDocumentManagerImpl.java:620)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.a(CoreCommandProcessor.java:149)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:109)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:99)
	at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.reloadFromDisk(FileDocumentManagerImpl.java:620)
	at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.reloadFiles(FileDocumentManagerImpl.java:512)
	at limitedwip.autorevert.components.IdeAdapter$2.run(IdeAdapter.java:68)
	at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:934)
	at limitedwip.autorevert.components.IdeAdapter.revertCurrentChangeList(IdeAdapter.java:53)
	at limitedwip.autorevert.AutoRevert.onTimer(AutoRevert.java:69)
	at limitedwip.autorevert.components.AutoRevertComponent$1$1.run(AutoRevertComponent.java:31)
	at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.a(LaterInvocator.java:417)
	at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.run(LaterInvocator.java:401)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
	at com.intellij.ide.IdeEventQueue.g(IdeEventQueue.java:843)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:679)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:391)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Option to force entry of the commit message

I would like to have an option to force the entry of a new commit message before committing. I can use the commit dialog, but the old message stays there by default so if I forget to adapt it then the history is wrong / confusing. Maybe the message in the commit dialog can be cleared when it is opened (it won't allow an empty commit message to be used), or maybe there could be another option to enter a commit message through a separate dialog before committing.

Is there a way to disable by project ?

I have a bunch of projects and would like to activate by project.

Is this a feature that would be feasible ?

(That said, this code is really cool :-) )

Commits on Compound test when one fails

The plugin commits if one set of compound tests pass. It would make more sense to commit only after they both pass. I'm trying to run unit tests along with e2e protractor tests on a react application. I find it's the most efficient way of doing TDD using Test && commit methodologies on react.

image

TCR: Option to `--amend` previous commit (or allow configuration of the commit command)

Hello @dkandalov,

First of all, I'd like to mention that this is an amazing plug-in overall. Thank you very much for making it available for everyone! 😄

Only thing I'm wondering is if it is possible customize how the commits are added with a bit more flexibility.
For example, I'd like an option for amending the previous commit added via TCR between each push, to avoid creating a huge list of relatively meaningless commits in sequence. For instance, let's say that to refactor something a bit bigger, e.g. switch-case into polymorphic dispatch, takes about 10 to 15 TCR cycles. Either we leave all commits in sequence with the same name, or we squash those commits into one which describes the entire refactoring. In such cases it would be better to write the first commit message, and have the following TCR cycles amending it. By "first commit", I mean the first change after being in sync with remote, so a git push would be the trigger for resetting the amend behavior, asking for a new commit message in the next TCR cycle, then continuing with the amends.

I realize this may be a very personal style, so in that case, I'd just like to suggest way to "tweak" the git commands that are sent on each passing test run, to make this logic happen. I believe that something like a "shell script to be executed on test pass" could do the trick.

feature idea: option to use test name for commit message in TCR mode

Hi Dmitry,

Thanks for this plugin!

Have you considered an option to use the name of the test as the commit message in TCR mode? It would probably exceed the commit summary length, but it would be more informative than any other option.

For example

if I run ... ...then the commit message is
displaysTheCurrentTime in the class NiftyWidgetTest "NiftyWidgetTest.displaysTheCurrentTime"
NiftyWidgetTest "NiftyWidgetTest"
all the tests in the package com.nifty.widgets "Tests in 'com.nifty.widgets'"

That last one is not a great commit message, but it's not worse than "wip" or repeating the last commit.

I don't know what it would take to make that work, I haven't taken a close look at the code for the plugin (and haven't written an intellij plugin before).

Cheers!
Alex

java.lang.AssertionError: Already disposed: Project

java.lang.AssertionError: Already disposed: Project (Disposed) xxxx
	at com.intellij.openapi.components.impl.ComponentManagerImpl.lambda$throwAlreadyDisposed$1(ComponentManagerImpl.java:245)
	at com.intellij.openapi.application.ReadAction.lambda$run$1(ReadAction.java:53)
	at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:970)
	at com.intellij.openapi.application.ReadAction.compute(ReadAction.java:57)
	at com.intellij.openapi.application.ReadAction.run(ReadAction.java:53)
	at com.intellij.openapi.components.impl.ComponentManagerImpl.throwAlreadyDisposed(ComponentManagerImpl.java:243)
	at com.intellij.openapi.components.impl.ComponentManagerImpl.getPicoContainer(ComponentManagerImpl.java:236)
	at com.intellij.openapi.components.impl.ComponentManagerImpl.getComponent(ComponentManagerImpl.java:146)
	at com.intellij.openapi.vcs.ProjectLevelVcsManager.getInstance(ProjectLevelVcsManager.java:41)
	at limitedwip.common.vcs.Revert_changelistKt.defaultChangeList(revert-changelist.kt:67)
	at limitedwip.autorevert.components.AutoRevertComponent$projectOpened$1$onUpdate$1.run(AutorevertComponent.kt:29)
	at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.doRun(LaterInvocator.java:435)
	at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.runNextEvent(LaterInvocator.java:419)
	at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.run(LaterInvocator.java:403)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:764)
	at java.awt.EventQueue.access$500(EventQueue.java:98)
	at java.awt.EventQueue$3.run(EventQueue.java:715)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:734)
	at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:747)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:696)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:391)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Commit fails if reformat / optimise imports is enabled

I have automatic code reformatting and optimise imports enabled (to keep code consistent). When tests are green then the WIP commit fails, presumably because the code has been modified again between the test success and the actual commit.

These automatic code updates should be ignored by the WIP check. You can still force the commit, but that seems like a bad habit to do on a regular basis.

Slow operations are prohibited on EDT

java.lang.Throwable: Slow operations are prohibited on EDT. See SlowOperations.assertSlowOperationsAreAllowed javadoc.
	at com.intellij.openapi.diagnostic.Logger.error(Logger.java:376)
	at com.intellij.util.SlowOperations.assertSlowOperationsAreAllowed(SlowOperations.java:95)
	at com.intellij.workspaceModel.core.fileIndex.impl.WorkspaceFileIndexDataImpl.ensureIsUpToDate(WorkspaceFileIndexDataImpl.kt:130)
	at com.intellij.workspaceModel.core.fileIndex.impl.WorkspaceFileIndexDataImpl.getFileInfo(WorkspaceFileIndexDataImpl.kt:75)
	at com.intellij.workspaceModel.core.fileIndex.impl.WorkspaceFileIndexImpl.getFileInfo(WorkspaceFileIndexImpl.kt:247)
	at com.intellij.workspaceModel.core.fileIndex.impl.WorkspaceFileIndexImpl.findFileSet(WorkspaceFileIndexImpl.kt:203)
	at com.intellij.workspaceModel.core.fileIndex.impl.WorkspaceFileIndexImpl.isInContent(WorkspaceFileIndexImpl.kt:69)
	at com.intellij.openapi.roots.impl.ProjectFileIndexImpl.isInContent(ProjectFileIndexImpl.java:206)
	at com.intellij.openapi.project.ProjectLocatorImpl.isUnder(ProjectLocatorImpl.java:58)
	at com.intellij.openapi.project.ProjectLocatorImpl.lambda$guessProjectForFile$0(ProjectLocatorImpl.java:47)
	at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:912)
	at com.intellij.openapi.application.ReadAction.compute(ReadAction.java:75)
	at com.intellij.openapi.project.ProjectLocatorImpl.guessProjectForFile(ProjectLocatorImpl.java:45)
	at com.intellij.openapi.vfs.encoding.EncodingManagerImpl.guessProject(EncodingManagerImpl.java:260)
	at com.intellij.openapi.vfs.encoding.EncodingManagerImpl.getEncoding(EncodingManagerImpl.java:233)
	at com.intellij.openapi.fileEditor.impl.LoadTextUtil.getDefaultCharsetFromEncodingManager(LoadTextUtil.java:266)
	at com.intellij.openapi.fileEditor.impl.LoadTextUtil.guessFromContent(LoadTextUtil.java:321)
	at com.intellij.openapi.fileEditor.impl.LoadTextUtil.detectHardCharset(LoadTextUtil.java:246)
	at com.intellij.openapi.fileEditor.impl.LoadTextUtil.detectInternalCharsetAndSetBOM(LoadTextUtil.java:275)
	at com.intellij.openapi.fileEditor.impl.LoadTextUtil.detectCharsetAndSetBOM(LoadTextUtil.java:261)
	at com.intellij.openapi.vfs.newvfs.impl.VirtualFileImpl.lambda$contentsToByteArray$0(VirtualFileImpl.java:128)
	at com.intellij.openapi.application.impl.ApplicationImpl.executeByImpatientReader(ApplicationImpl.java:184)
	at com.intellij.openapi.vfs.newvfs.impl.VirtualFileImpl.contentsToByteArray(VirtualFileImpl.java:128)
	at com.intellij.openapi.vfs.newvfs.impl.VirtualFileImpl.contentsToByteArray(VirtualFileImpl.java:109)
	at com.intellij.openapi.fileEditor.impl.LoadTextUtil.loadText(LoadTextUtil.java:511)
	at com.intellij.openapi.fileEditor.impl.LoadTextUtil.loadText(LoadTextUtil.java:491)
	at com.intellij.openapi.fileEditor.impl.FileDocumentManagerBase.loadText(FileDocumentManagerBase.java:105)
	at com.intellij.openapi.fileEditor.impl.FileDocumentManagerBase.getDocument(FileDocumentManagerBase.java:61)
	at limitedwip.watchdog.components.ChangeSizeWatcher.document(ChangeSizeWatcher.kt:88)
	at limitedwip.watchdog.components.ChangeSizeWatcher.access$document(ChangeSizeWatcher.kt:24)
	at limitedwip.watchdog.components.ChangeSizeWatcher$calculateCurrentChangeListSizeInLines$1.compute(ChangeSizeWatcher.kt:50)
	at limitedwip.watchdog.components.ChangeSizeWatcher$calculateCurrentChangeListSizeInLines$1.compute(ChangeSizeWatcher.kt:24)
	at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:897)
	at limitedwip.watchdog.components.ChangeSizeWatcher.calculateCurrentChangeListSizeInLines(ChangeSizeWatcher.kt:46)
	at limitedwip.watchdog.components.WatchdogIde.calculateCurrentChangeListSizeInLines(WatchdogIde.kt:34)
	at limitedwip.watchdog.Watchdog.onTimer(Watchdog.kt:19)
	at limitedwip.watchdog.components.WatchdogComponent$start$3$onUpdate$1.invoke(WatchdogComponent.kt:49)
	at limitedwip.watchdog.components.WatchdogComponent$start$3$onUpdate$1.invoke(WatchdogComponent.kt:41)
	at limitedwip.common.vcs.Commit_and_pushKt$sam$java_lang_Runnable$0.run(commit-and-push.kt)
	at com.intellij.openapi.application.TransactionGuardImpl$1.run(TransactionGuardImpl.java:194)
	at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:846)
	at com.intellij.openapi.application.impl.ApplicationImpl$4.run(ApplicationImpl.java:466)
	at com.intellij.openapi.application.impl.RwLockHolder.runWithEnabledImplicitRead(RwLockHolder.kt:75)
	at com.intellij.openapi.application.impl.RwLockHolder.runWithImplicitRead(RwLockHolder.kt:67)
	at com.intellij.openapi.application.impl.ApplicationImpl.runWithImplicitRead(ApplicationImpl.java:1433)
	at com.intellij.openapi.application.impl.FlushQueue.doRun(FlushQueue.java:82)
	at com.intellij.openapi.application.impl.FlushQueue.runNextEvent(FlushQueue.java:124)
	at com.intellij.openapi.application.impl.FlushQueue.flushNow(FlushQueue.java:44)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:792)
	at java.desktop/java.awt.EventQueue$3.run(EventQueue.java:739)
	at java.desktop/java.awt.EventQueue$3.run(EventQueue.java:733)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:761)
	at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.kt:687)
	at com.intellij.ide.IdeEventQueue._dispatchEvent$lambda$12(IdeEventQueue.kt:588)
	at com.intellij.openapi.application.impl.RwLockHolder.runWithoutImplicitRead(RwLockHolder.kt:44)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.kt:588)
	at com.intellij.ide.IdeEventQueue.access$_dispatchEvent(IdeEventQueue.kt:71)
	at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1$1.compute(IdeEventQueue.kt:354)
	at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1$1.compute(IdeEventQueue.kt:353)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:793)
	at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1.invoke(IdeEventQueue.kt:353)
	at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1.invoke(IdeEventQueue.kt:348)
	at com.intellij.ide.IdeEventQueueKt.performActivity$lambda$1(IdeEventQueue.kt:1006)
	at com.intellij.openapi.application.TransactionGuardImpl.performActivity(TransactionGuardImpl.java:106)
	at com.intellij.ide.IdeEventQueueKt.performActivity(IdeEventQueue.kt:1006)
	at com.intellij.ide.IdeEventQueue.dispatchEvent$lambda$7(IdeEventQueue.kt:348)
	at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:851)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.kt:390)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:207)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:92)

IllegalStateException: profileName must not be null

java.lang.IllegalStateException: profileName must not be null
	at limitedwip.tcr.components.UnitTestsWatcher$start$2.notify(UnitTestsWatcher.kt:37)
	at jdk.internal.reflect.GeneratedMethodAccessor1048.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.intellij.util.messages.impl.MessageBusConnectionImpl.deliverMessage(MessageBusConnectionImpl.java:102)
	at com.intellij.util.messages.impl.MessageBusImpl.doPumpMessages(MessageBusImpl.java:446)
	at com.intellij.util.messages.impl.MessageBusImpl.pumpWaitingBuses(MessageBusImpl.java:406)
	at com.intellij.util.messages.impl.MessageBusImpl.pumpMessages(MessageBusImpl.java:395)
	at com.intellij.util.messages.impl.MessageBusImpl.pumpMessages(MessageBusImpl.java:379)
	at com.intellij.util.messages.impl.MessageBusImpl.sendMessage(MessageBusImpl.java:370)
	at com.intellij.util.messages.impl.MessageBusImpl.lambda$createTopicHandler$1(MessageBusImpl.java:242)
	at com.sun.proxy.$Proxy44.setInfo(Unknown Source)
	at com.intellij.openapi.wm.StatusBar$Info.set(StatusBar.java:49)
	at com.intellij.notification.LogModel.setStatusMessage(LogModel.java:91)
	at com.intellij.notification.LogModel.addNotification(LogModel.java:65)
	at com.intellij.notification.EventLog$ProjectTracker.printNotification(EventLog.java:498)
	at com.intellij.notification.EventLog$ProjectTracker.access$100(EventLog.java:457)
	at com.intellij.notification.EventLog$ProjectTracker$1.notify(EventLog.java:474)
	at jdk.internal.reflect.GeneratedMethodAccessor1048.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.intellij.util.messages.impl.MessageBusConnectionImpl.deliverMessage(MessageBusConnectionImpl.java:102)
	at com.intellij.util.messages.impl.MessageBusImpl.doPumpMessages(MessageBusImpl.java:446)
	at com.intellij.util.messages.impl.MessageBusImpl.pumpWaitingBuses(MessageBusImpl.java:406)
	at com.intellij.util.messages.impl.MessageBusImpl.pumpMessages(MessageBusImpl.java:395)
	at com.intellij.util.messages.impl.MessageBusImpl.pumpMessages(MessageBusImpl.java:379)
	at com.intellij.util.messages.impl.MessageBusImpl.sendMessage(MessageBusImpl.java:372)
	at com.intellij.util.messages.impl.MessageBusImpl.lambda$createTopicHandler$1(MessageBusImpl.java:242)
	at com.sun.proxy.$Proxy43.notify(Unknown Source)
	at com.intellij.notification.Notifications$Bus.doNotify(Notifications.java:76)
	at com.intellij.notification.Notifications$Bus.lambda$notify$1(Notifications.java:70)
	at com.intellij.util.ui.UIUtil.invokeLaterIfNeeded(UIUtil.java:2458)
	at com.intellij.notification.Notifications$Bus.notify(Notifications.java:70)
	at com.intellij.notification.Notification.notify(Notification.java:340)
	at com.intellij.execution.testframework.TestsUIUtil.notifyByBalloon(TestsUIUtil.java:162)
	at com.intellij.execution.testframework.sm.runner.ui.SMTestRunnerResultsForm.lambda$onTestingFinished$2(SMTestRunnerResultsForm.java:310)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:776)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:746)
	at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:817)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:766)
	at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:405)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:704)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:404)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Do you have plans to support this plugin in Rider?

Hi,

I was using this plugin when I was working with Java, but now I'm working with C# and using Rider.
The plugin is available to download and install, but not work as expected. The TCR is not working :/

I would love to have this working on Rider, do you have checked if is something viable to do this?

Press "ok" before auto-reverting

Hi all,

First of all, thanks for this amazing tool! This is exactly what I was looking for.

I've only started applying this idea of only keeping changes to X minutes before reverting, so I'm still learning and it can be frustrating at times when you're almost done with something or something interrupted you and you forgot to stop the timer and you realize all the changes are gone.

I would very much appreciate if there was some sort of (opt-in) confirmation prompt before reverting the code. Then, either restart the timer (potentially only one more time before reverting without the prompt) or use shorter timers (eg 5 min instead of 15) as many times as needed prompting for the revert at the end of each one.

I understand this goes in the opposite direction of the technique and plugin, but as a beginner (and especially when debugging something complex), this would be of immense help!

Thanks and congrats again for the tool!

Reset Time if the code is reverted

Scenario:

Using the clock as the constraint.

editing one File -> Editor -> mouse right click -> Git -> revert

resets the file in the original state. The clock does not change.

Improvement:

Reset the clock as well.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.