File does not reload in editor when quickly changed externally after making modifications #12077

Closed
wagerfield opened this Issue Sep 15, 2016 · 23 comments

Comments

Projects
None yet
5 participants
@wagerfield
  • VSCode Version: 1.5.2
  • Mac OS Version: 10.11.6

Steps to Reproduce:

Step 1: Create a project that uses webpack to bundle some JS—running it through eslint first and telling eslint to fix any errors where possible:

// package.json
{
  "scripts": {
    "build": "webpack",
    "watch": "webpack --watch"
  },
  "devDependencies": {
    "eslint": "^3.5.0",
    "eslint-loader": "^1.5.0",
    "webpack": "^1.13.2"
  }
}
// webpack.config.js
module.exports = {
  entry: './index.js',
  output: {
    filename: 'bundle.js'
  },
  module: {
    preLoaders: [{
      test: /\.js$/,
      loader: 'eslint',
      query: {
        fix: true
      }
    }]
  }
}

Step 2: Create an .eslintrc file that has a rule that can be automatically fixed—like "semi": [2, "never"]:

// .eslintrc
{
  "rules": {
    "semi": [2, "never"]
  } 
}

Step 3: Add some code in index.js (the webpack entry file) that breaks this rule:

// index.js
var foo = 'foo';

Step 4: Run webpack in watch mode npm run watch

Step 5: Observe that the trailing semi colon in index.js has been automatically removed by eslint and that the file in VS Code reflect this

Step 6: With webpack still watching the file, add the semi colon back in again from within VS Code and then observe that VS Code does not refresh/reload this file when it is fixed a second time by eslint

Step 7: Confirm that index.js has been fixed by inspecting it in your file system or closing the file in VS Code and then opening it again

Notice that VS Code refreshes the file as expected when the file is first fixed, but on each subsequent fix, the file does not reload/refresh in VS Code. This works fine in SublimeText, so I assume it is a bug of VS Code's file watcher.

@bpasero bpasero added the bug label Sep 15, 2016

@bpasero bpasero added this to the Backlog milestone Sep 15, 2016

@bpasero bpasero self-assigned this Sep 15, 2016

@bpasero

This comment has been minimized.

Show comment
Hide comment
@bpasero

bpasero Sep 16, 2016

Member

Great description, easy enough to reproduce for me. The issue is that we have a time-window where we ignore any change on disk (2 seconds currently). The reason is that when you save the file by making changes from VS Code, a file event is generated right after. We typically want to load the file contents from disk when such an event happens to see if the contents have changed. However we cannot distinguish a change done by the user within Code and a change outside Code (so we use the 2 seconds timeout as hack/workaround to not load the file after each change from the user).

I never really liked this hack, so maybe a better approach would be to load the file on each change and check the mtime to see if the contents have changed or not. This approach is problematic though in case someone tampers with the mtimes.

Member

bpasero commented Sep 16, 2016

Great description, easy enough to reproduce for me. The issue is that we have a time-window where we ignore any change on disk (2 seconds currently). The reason is that when you save the file by making changes from VS Code, a file event is generated right after. We typically want to load the file contents from disk when such an event happens to see if the contents have changed. However we cannot distinguish a change done by the user within Code and a change outside Code (so we use the 2 seconds timeout as hack/workaround to not load the file after each change from the user).

I never really liked this hack, so maybe a better approach would be to load the file on each change and check the mtime to see if the contents have changed or not. This approach is problematic though in case someone tampers with the mtimes.

@bpasero bpasero changed the title from File doesn't reload/refresh when automatically fixed by eslint when webpack is watching for changes to File does not reload in editor when quickly changed externally after making modifications Sep 16, 2016

@wagerfield

This comment has been minimized.

Show comment
Hide comment
@wagerfield

wagerfield Sep 16, 2016

Great, thanks for the rapid response! Why is it not possible for VS Code to differentiate between when the file was modified externally and when it was modified by VS Code itself? Surely there's an event within the editor that is fired when the editor is told to save? What happens if you remove this 2 second threshold?

Great, thanks for the rapid response! Why is it not possible for VS Code to differentiate between when the file was modified externally and when it was modified by VS Code itself? Surely there's an event within the editor that is fired when the editor is told to save? What happens if you remove this 2 second threshold?

@bpasero

This comment has been minimized.

Show comment
Hide comment
@bpasero

bpasero Sep 16, 2016

Member

@wagerfield yes we do have events internally when you change the file in VS Code, but we also have file watchers that just fire on any change that happens on the file on disk. This guy does not know if the change happened inside Code our outside.

If we take out the check today, I think nothing super bad would happen, we just have an extra disk access each time you save the file (shortly after actually due to the delay in the eventing).

Member

bpasero commented Sep 16, 2016

@wagerfield yes we do have events internally when you change the file in VS Code, but we also have file watchers that just fire on any change that happens on the file on disk. This guy does not know if the change happened inside Code our outside.

If we take out the check today, I think nothing super bad would happen, we just have an extra disk access each time you save the file (shortly after actually due to the delay in the eventing).

@wagerfield

This comment has been minimized.

Show comment
Hide comment
@wagerfield

wagerfield Sep 16, 2016

Perhaps that's an option? No idea how SublimeText handles this, but if you repeat the steps above in ST you don't experience this issue, so perhaps they haven't implemented this threshold?

Perhaps that's an option? No idea how SublimeText handles this, but if you repeat the steps above in ST you don't experience this issue, so perhaps they haven't implemented this threshold?

@bpasero

This comment has been minimized.

Show comment
Hide comment
@bpasero

bpasero Sep 16, 2016

Member

Yeah I am quite sure we are the only ones doing this :). Though for ST the experience is also different: if they detect a change on disk, they open a dialog asking to reload the file. Or am I wrong?

Member

bpasero commented Sep 16, 2016

Yeah I am quite sure we are the only ones doing this :). Though for ST the experience is also different: if they detect a change on disk, they open a dialog asking to reload the file. Or am I wrong?

@wagerfield

This comment has been minimized.

Show comment
Hide comment
@wagerfield

wagerfield Sep 16, 2016

Putting VSC and ST side-by-side and modifying a file that is open in each editor causes a different behaviour to happen in each editor. Neither trigger a prompt/dialog as you mentioned—though I have seen this dialog in ST in the past, so I know what you're referring to.

If I modify a file in VSC, then ST doesn't update the file until I focus the editor, so perhaps it disables the file watchers when the editor (ST) is out of focus, but then re-reads all the files that are currently open in ST when you focus the editor?

If I modify a file from ST, then VSC updates the file immediately—VSC doesn't have to be in focus. I assume the you aren't removing/disabling the file watchers when VSC is out of focus.

Neither editor display prompts letting you know that the file had changed.

Now, if you run npm run watch as per the example above, we see another set of behaviours when the file is being modified by eslint from the shell...

With the semicolon added before of running npm run watch and with the terminal in focus...

screen shot 2016-09-16 at 11 11 57

npm run watch will cause eslint to fix the error in the file, BUT the changes will only be reflected in VSC. ST won't display the changes until I focus the editor.

screen shot 2016-09-16 at 11 15 07

As you might expect, when I focus ST, the changes are reflected.

With webpack still watching the files, if I modify the file from within VSC—adding the semicolon, eslint runs, fixes the file but nothing changes in ST (because it's not in focus, so it won't have shown the semicolon being added by VSC and then removed by eslint).

If I do this in reverse and modify the file from ST, then VSC shows the added semicolon for a brief moment and then removes it again after eslint has performed its fix.

The difference here is that the file in ST is also refreshed following eslint modifying it—ST is in focus, so the watchers are active.

Perhaps ST has a much smaller tolerance, or no tolerance at all?

Putting VSC and ST side-by-side and modifying a file that is open in each editor causes a different behaviour to happen in each editor. Neither trigger a prompt/dialog as you mentioned—though I have seen this dialog in ST in the past, so I know what you're referring to.

If I modify a file in VSC, then ST doesn't update the file until I focus the editor, so perhaps it disables the file watchers when the editor (ST) is out of focus, but then re-reads all the files that are currently open in ST when you focus the editor?

If I modify a file from ST, then VSC updates the file immediately—VSC doesn't have to be in focus. I assume the you aren't removing/disabling the file watchers when VSC is out of focus.

Neither editor display prompts letting you know that the file had changed.

Now, if you run npm run watch as per the example above, we see another set of behaviours when the file is being modified by eslint from the shell...

With the semicolon added before of running npm run watch and with the terminal in focus...

screen shot 2016-09-16 at 11 11 57

npm run watch will cause eslint to fix the error in the file, BUT the changes will only be reflected in VSC. ST won't display the changes until I focus the editor.

screen shot 2016-09-16 at 11 15 07

As you might expect, when I focus ST, the changes are reflected.

With webpack still watching the files, if I modify the file from within VSC—adding the semicolon, eslint runs, fixes the file but nothing changes in ST (because it's not in focus, so it won't have shown the semicolon being added by VSC and then removed by eslint).

If I do this in reverse and modify the file from ST, then VSC shows the added semicolon for a brief moment and then removes it again after eslint has performed its fix.

The difference here is that the file in ST is also refreshed following eslint modifying it—ST is in focus, so the watchers are active.

Perhaps ST has a much smaller tolerance, or no tolerance at all?

@bpasero

This comment has been minimized.

Show comment
Hide comment
@bpasero

bpasero Sep 16, 2016

Member

@wagerfield what happens when you make the edits inside ST, does it show the removed comma right after you save? I am a bit confused because I thought ST would show a dialog when a resource changed on disk to reload it. But maybe this dialog only shows when the file is actually dirty in the editor.

Member

bpasero commented Sep 16, 2016

@wagerfield what happens when you make the edits inside ST, does it show the removed comma right after you save? I am a bit confused because I thought ST would show a dialog when a resource changed on disk to reload it. But maybe this dialog only shows when the file is actually dirty in the editor.

@wagerfield

This comment has been minimized.

Show comment
Hide comment
@wagerfield

wagerfield Sep 16, 2016

If I have webpack watching the file for changes, then add a semicolon from within ST, the semicolon is added when I type it (so I can physically see it within the editor), then a split second later it is removed when eslint fixes and modifies the file.

If I have webpack watching the file for changes, then add a semicolon from within ST, the semicolon is added when I type it (so I can physically see it within the editor), then a split second later it is removed when eslint fixes and modifies the file.

@bpasero

This comment has been minimized.

Show comment
Hide comment
@bpasero

bpasero Sep 16, 2016

Member

@wagerfield are you loosing the undo history when this happens?

Member

bpasero commented Sep 16, 2016

@wagerfield are you loosing the undo history when this happens?

@wagerfield

This comment has been minimized.

Show comment
Hide comment
@wagerfield

wagerfield Sep 16, 2016

History is maintained in ST, but not in VSC.

If I open the index.js in ST with the semicolon in place and no history is in that file's session (CMD+Z does nothing), then I run npm run watcheslint fixes and changes index.js removing the semicolon in ST and this change is pushed onto the file's history in ST so that I can hit CMD+Z once to see the semicolon added back to the file.

I can repeat this loop by hitting CMD+S and observe the semicolon being removed again by eslint ad infinitum.

Doing this same exercise in VSC produces different results. If I open up index.js with the semicolon in place and no file session history, then I run npm run watch, eslint will fix and change the file—removing the semicolon. In VSC, this external change by eslint is not pushed onto the history—I cannot hit CMD+Z and have the semicolon added back into the file.

wagerfield commented Sep 16, 2016

History is maintained in ST, but not in VSC.

If I open the index.js in ST with the semicolon in place and no history is in that file's session (CMD+Z does nothing), then I run npm run watcheslint fixes and changes index.js removing the semicolon in ST and this change is pushed onto the file's history in ST so that I can hit CMD+Z once to see the semicolon added back to the file.

I can repeat this loop by hitting CMD+S and observe the semicolon being removed again by eslint ad infinitum.

Doing this same exercise in VSC produces different results. If I open up index.js with the semicolon in place and no file session history, then I run npm run watch, eslint will fix and change the file—removing the semicolon. In VSC, this external change by eslint is not pushed onto the history—I cannot hit CMD+Z and have the semicolon added back into the file.

@bpasero

This comment has been minimized.

Show comment
Hide comment
@bpasero

bpasero Sep 16, 2016

Member

OK interesting, I think we have to improve in this area 👍

Member

bpasero commented Sep 16, 2016

OK interesting, I think we have to improve in this area 👍

@cwgabel

This comment has been minimized.

Show comment
Hide comment
@cwgabel

cwgabel Sep 16, 2016

My problem is I externally (windows explorer) created a 'views' directory and copied files into it outside of VSC only to find the views directory show up in the VSC explorer but clicking on it did not expand (nor was there a directory icon next to to it). It is all fine once I restarted VSC. Running Window 7 with VSC 1.5.2. Not a big deal, always found the refresh you do to work flawlessly.

cwgabel commented Sep 16, 2016

My problem is I externally (windows explorer) created a 'views' directory and copied files into it outside of VSC only to find the views directory show up in the VSC explorer but clicking on it did not expand (nor was there a directory icon next to to it). It is all fine once I restarted VSC. Running Window 7 with VSC 1.5.2. Not a big deal, always found the refresh you do to work flawlessly.

@bpasero

This comment has been minimized.

Show comment
Hide comment
@bpasero

bpasero Sep 16, 2016

Member

There is also a refresh action within the explorer which should produce the same results as restarting.

Member

bpasero commented Sep 16, 2016

There is also a refresh action within the explorer which should produce the same results as restarting.

@oleksiipysanko

This comment has been minimized.

Show comment
Hide comment
@oleksiipysanko

oleksiipysanko Feb 28, 2017

Hi @wagerfield, @bpasero

I'm observing the exact same issue when working in recent VSCode (1.9.1). The problem is that I have a custom eslint setup (ES6 + react) and webpack build which autofixes (eslint --fix) any errors/warnings on file save.

VSCode is configured with "files.autoSave": "onFocusChange" option, so, for example when I edit following line:

const { props: { ...rest } } = this; to const { props: { ...rest } } = this removing trailing semicolon and switch to terminal webpack rebuilds project and eslint adds semicolon again through --fix. But I'm able to see this change in workspace only if I switch between some open files or other VSCode panes (like GIT, etc.). If I don't do this and start editing the file straight away, I'll had to compare through dialog making dev experience really poor.

Therefore, the question is - are there any workaround for now? Maybe some file refresh option to invoke manually of which I don't know? I've tried to click explorer refresh button after change as @bpasero suggested, but it doesn't reload currently opened file

Thanks

oleksiipysanko commented Feb 28, 2017

Hi @wagerfield, @bpasero

I'm observing the exact same issue when working in recent VSCode (1.9.1). The problem is that I have a custom eslint setup (ES6 + react) and webpack build which autofixes (eslint --fix) any errors/warnings on file save.

VSCode is configured with "files.autoSave": "onFocusChange" option, so, for example when I edit following line:

const { props: { ...rest } } = this; to const { props: { ...rest } } = this removing trailing semicolon and switch to terminal webpack rebuilds project and eslint adds semicolon again through --fix. But I'm able to see this change in workspace only if I switch between some open files or other VSCode panes (like GIT, etc.). If I don't do this and start editing the file straight away, I'll had to compare through dialog making dev experience really poor.

Therefore, the question is - are there any workaround for now? Maybe some file refresh option to invoke manually of which I don't know? I've tried to click explorer refresh button after change as @bpasero suggested, but it doesn't reload currently opened file

Thanks

@bpasero

This comment has been minimized.

Show comment
Hide comment
@bpasero

bpasero Feb 28, 2017

Member

@oleksiipysanko this is a good scenario and there is no workaround currently other than letting an extension do the fixing during save.

@egamma isn't this something you are looking into to automatically fix warnings on save from the ESLint extension?

Member

bpasero commented Feb 28, 2017

@oleksiipysanko this is a good scenario and there is no workaround currently other than letting an extension do the fixing during save.

@egamma isn't this something you are looking into to automatically fix warnings on save from the ESLint extension?

@oleksiipysanko

This comment has been minimized.

Show comment
Hide comment
@oleksiipysanko

oleksiipysanko Feb 28, 2017

@bpasero Its interesting, because I'm using command line generator to update migrations for my API and having migration file opened in VSCode after invoking command from terminal (which modifies opened file) I'm able to see changes instantly in editor.

So, as I can understand the problem is in 2 sec timeout and if eslint will modify the file after this delay editor will pick up changes, right?

@bpasero Its interesting, because I'm using command line generator to update migrations for my API and having migration file opened in VSCode after invoking command from terminal (which modifies opened file) I'm able to see changes instantly in editor.

So, as I can understand the problem is in 2 sec timeout and if eslint will modify the file after this delay editor will pick up changes, right?

@oleksiipysanko

This comment has been minimized.

Show comment
Hide comment
@oleksiipysanko

oleksiipysanko Feb 28, 2017

@bpasero A thing to note - I'm not using VSCode Eslint extension, eslint runs from command line, because build should be supported across different IDEs

@bpasero A thing to note - I'm not using VSCode Eslint extension, eslint runs from command line, because build should be supported across different IDEs

@bpasero

This comment has been minimized.

Show comment
Hide comment
@bpasero

bpasero Feb 28, 2017

Member

@oleksiipysanko yeah this is not a problem when you have not edited the file in 2s, it only shows up if you edit and during 2s time another process changes the file.

Member

bpasero commented Feb 28, 2017

@oleksiipysanko yeah this is not a problem when you have not edited the file in 2s, it only shows up if you edit and during 2s time another process changes the file.

@oleksiipysanko

This comment has been minimized.

Show comment
Hide comment
@oleksiipysanko

oleksiipysanko Feb 28, 2017

@bpasero thx for quick response, I'll try to resolve it this way

@bpasero thx for quick response, I'll try to resolve it this way

@bpasero bpasero modified the milestones: March 2017, Backlog Mar 1, 2017

@bpasero bpasero closed this in 72caa40 Mar 1, 2017

@bpasero

This comment has been minimized.

Show comment
Hide comment
@bpasero

bpasero Mar 1, 2017

Member

I took out the arbitrary 2s time window where we ignore updates to the editor to fix this issue an probably a bunch of other related issues. I hope this does not break things, let's see how it goes during the milestone in our insider builds.

Member

bpasero commented Mar 1, 2017

I took out the arbitrary 2s time window where we ignore updates to the editor to fix this issue an probably a bunch of other related issues. I hope this does not break things, let's see how it goes during the milestone in our insider builds.

@oleksiipysanko

This comment has been minimized.

Show comment
Hide comment
@oleksiipysanko

oleksiipysanko Mar 3, 2017

Hi @bpasero, sorry for disturbing, I see that this issue is set for eof march milestone, though there was an update recently, so I though that it could be included there since you've closed the issue, is it?

Thanks

Hi @bpasero, sorry for disturbing, I see that this issue is set for eof march milestone, though there was an update recently, so I though that it could be included there since you've closed the issue, is it?

Thanks

@bpasero

This comment has been minimized.

Show comment
Hide comment
@bpasero

bpasero Mar 3, 2017

Member

@oleksiipysanko yes I took out the 2s window, you should see the fix in our insiders release. You can give our preview releases a try from: http://code.visualstudio.com/Download#insiders

Member

bpasero commented Mar 3, 2017

@oleksiipysanko yes I took out the 2s window, you should see the fix in our insiders release. You can give our preview releases a try from: http://code.visualstudio.com/Download#insiders

@oleksiipysanko

This comment has been minimized.

Show comment
Hide comment
@oleksiipysanko

oleksiipysanko Mar 3, 2017

@bpasero oh, great, thanks for the tip!

@bpasero oh, great, thanks for the tip!

@roblourens roblourens added the verified label Mar 30, 2017

@Microsoft Microsoft locked and limited conversation to collaborators Nov 18, 2017

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.