MiguelCastillo / Brackets-wsSanitizer

White Space Sanitizer for Brackets will help you keep your sanity by keeping your white spaces and tabs consistent
MIT License
36 stars 8 forks source link

Repeatedly Saves File, Indefinitely #11

Open lewishowles opened 9 years ago

lewishowles commented 9 years ago

When saving a file with the latest version of wsSanitizer, often it will repeatedly save the file continuously, making the file unusable.

This can be seen by the 'unsaved changes' icon flicking on and off and files constantly being passed to external compilers.

A recent commit seems to have suggested this was fixed (or a similar thing), but in this case it doesn't seem to be.

I have tried removing the plugin entirely and getting the latest version from the extensions GUI to no avail.

Is there a method of seeing if there are any clashes with other plugins?

joepie91 commented 9 years ago

I also started experiencing this some 20 minutes ago. I haven't experienced this issue before that.

MiguelCastillo commented 9 years ago

Yeah that's a problem. I hate that bug. I personally havent ran into it since I "fixed it"... What version of Brackets are you folks using? And what OS?

joepie91 commented 9 years ago

Brackets:

Release 1.2 experimental build 1.2.0-15697 (release 8f82e2a97) 
build timestamp: Tue Feb 24 2015 21:16:20 GMT-0800

OS: openSUSE 13.1 x86_64

Extension list:

sven@linux-etoq:~/.config/Brackets/extensions/user> cat */package.json | jq [.name,.version]
[
  "angularui.angularjs",
  "1.1.2"
]
[
  "asgerf.bracket-rename",
  "0.2.8"
]
[
  "a-type.pjs-syntax-highlighting",
  "1.0.0"
]
[
  "bigeyex.brackets-wordhint",
  "1.0.2"
]
[
  "blueprint.outliner",
  "0.9.2"
]
[
  "brackets-angularjs-codehints",
  "0.0.2"
]
[
  "brackets-apache-syntax",
  "1.0.0"
]
[
  "brackets-beautify",
  "1.1.6"
]
[
  "brackets-boilerplate",
  "0.4.3"
]
[
  "brackets-bower",
  "0.2.5"
]
[
  "brackets-builder",
  "0.0.3"
]
[
  "brackets-display-shortcuts",
  "1.2.2"
]
[
  "brackets-emmet",
  "1.2.2"
]
[
  "brackets-go",
  "0.0.2"
]
[
  "brackets-html5codehints",
  "1.2.1"
]
[
  "brackets-indentator",
  "1.0.3"
]
[
  "brackets-indent-guides",
  "1.3.3"
]
[
  "brackets-integrated-development",
  "0.5.59"
]
[
  "brackets-livescript",
  "0.0.2"
]
[
  "brackets-lorem-ipsum",
  "1.0.2"
]
[
  "brackets-morecsscodehints",
  "1.2.0"
]
[
  "brackets-nodejs",
  "1.4.0"
]
[
  "brackets-preferences-viewer",
  "1.0.5"
]
[
  "brackets-rezymer",
  "1.2.0"
]
[
  "brackets-rst",
  "1.0.2"
]
[
  "brackets-smooth-scroll",
  "0.0.1"
]
[
  "brackets-sort-text",
  "0.1.3"
]
[
  "brackets.swatcher",
  "1.1.0"
]
[
  "brackets-textile",
  "1.0.1"
]
[
  "brackets-wakatime",
  "1.0.4"
]
[
  "busykai.indent-right",
  "0.0.5"
]
[
  "camden.caniuse",
  "2.0.9"
]
[
  "codehighlighter-switcher",
  "1.0.1"
]
[
  "colorhints",
  "1.1.1"
]
[
  "com.nextrevision.puppet-syntax",
  "0.1.6"
]
[
  "crot4lus.brackets-tabs",
  "0.1.2"
]
[
  "custom-placeholdit-for-brackets-jara.phit",
  "0.0.2"
]
[
  "dart",
  "1.0.0"
]
[
  "dnbard.extensions-rating",
  "0.6.4"
]
[
  "dnbard.postman",
  "0.1.1"
]
[
  "dnbard.projects",
  "0.1.6"
]
[
  "donebyexperts.quick-show-in-file-tree",
  "0.0.1"
]
[
  "donutteam.pastebin",
  "1.0.0"
]
[
  "drewkoch.icons",
  "1.3.1"
]
[
  "enturn.quick-search",
  "1.1.4"
]
[
  "fede91.brackets-preferences-ui",
  "1.1.0"
]
[
  "fezvrasta.brackets-upper-titlebar",
  "1.0.7"
]
[
  "francescolaffi.vagrant",
  "0.1.0"
]
[
  "georapbox.brackets-notes",
  "1.0.8"
]
[
  "growlscript.brackets.classcompletion",
  "0.2.1"
]
[
  "gruehle.exclude-folders",
  "0.1.0"
]
[
  "gruehle.markdown-preview",
  "1.0.10"
]
[
  "hirse.outline-list",
  "0.5.1"
]
[
  "insya.units",
  "0.0.6"
]
[
  "io.brackets.color-palette",
  "2.0.1"
]
[
  "io.brackets-sass-code-hints",
  "0.1.0"
]
[
  "io.brackets.svg-code-hints",
  "1.1.0"
]
[
  "jade",
  "2.0.0"
]
[
  "jasonsanjose.brackets-sass",
  "2.0.1-109"
]
[
  "jeffbooher.new-project",
  "0.4.93"
]
[
  "jeremylee.brackets-smarty",
  "1.0.0"
]
[
  "johnwu.brackets-code-connect",
  "0.1.1"
]
[
  "josecols.python-tidy",
  "1.0.1"
]
[
  "jrowny.brackets.snippets",
  "1.1.0"
]
[
  "lb4b",
  "0.0.2"
]
[
  "lh.brackets.syntax-highlighter-jinja2",
  "1.0.0"
]
[
  "lka.gistr",
  "0.3.2"
]
[
  "lua",
  "1.0.0"
]
[
  "mikaeljorhult.brackets-autoprefixer",
  "0.5.20"
]
[
  "mikaeljorhult.brackets-todo",
  "0.8.1"
]
[
  "mirc",
  "1.0.0"
]
[
  "notasz-uitheming",
  "1.0.0"
]
[
  "pflynn.brackets.commands.guide",
  "1.0.5"
]
[
  "pflynn.copy-as-html",
  "1.0.5"
]
[
  "pflynn.eval-in-browser",
  "1.0.2"
]
[
  "pflynn.everyscrub",
  "1.4.0"
]
[
  "pflynn.goto_last_edit",
  "1.0.1"
]
[
  "pflynn.jump-to-matching-brace",
  "1.1.0"
]
[
  "pflynn.reasonable-comments",
  "1.3.0"
]
[
  "pflynn.regex-editor",
  "1.1.3"
]
[
  "php-sig.php-smarthints",
  "1.1.3"
]
[
  "pretty_json",
  "0.1.2"
]
[
  "pythonista-dark",
  "1.0.0"
]
[
  "quickdocsjs",
  "1.6.5"
]
[
  "quickdocsphp",
  "1.4.7"
]
[
  "quickdocsregex",
  "0.1.1"
]
[
  "quick-require",
  "0.5.0"
]
[
  "ruby-blue",
  "1.3.1"
]
[
  "soimon.brackets-document-outliner",
  "1.0.2"
]
[
  "stripper-theme",
  "0.1.0"
]
[
  "themesforbrackets",
  "2.0.11"
]
[
  "theseus",
  "0.4.19"
]
[
  "tommalbran.brackets-fonts-viewer",
  "0.4.0"
]
[
  "tomorrow-night-bright",
  "1.0.2"
]
[
  "toshsharma.bookmarks",
  "1.0.1"
]
[
  "zaggino.brackets-git",
  "0.14.24"
]
MiguelCastillo commented 9 years ago

Holy smokes that's a lot of extension!! :D

MiguelCastillo commented 9 years ago

Can you easily reproduce the issue? What are the steps? Meaning... Your file has mixed tabs and spaces, and sanitizer converts them to tabs... Or is sanitizer converting to spaces?

joepie91 commented 9 years ago

Hehe yes, I went a little crazy. Hasn't really caused me any issues before, though :)

joepie91 commented 9 years ago

Whoops, ninja'd. It happened with a .js file when I tried to save it, even after restarts... doesn't seem to have anything to do with spacing, as far as I know it was consistent. It should be converting to tabs. If you have a sample file for me that works on your system, I can test it here?

MiguelCastillo commented 9 years ago

all my public projects use spaces... But the few that use tabs dont seem to cause me any issues. Let me take a look at the code. I know how the spot it could kinda sorta happen, but it's a nasty little timing issue. It basically boils down to the document save listener that triggers a sanitize... and once sanitize is done, I manually trigger the save again. So if there is a weird timing issue, that can get stuck in a loop. And I have a safety guard. So I am not sure how this can all happen.

https://github.com/MiguelCastillo/Brackets-wsSanitizer/blob/master/main.js#L48

I assume you are running v1.0.0?

lewishowles commented 9 years ago

In case it helps, I'm on Brackets 1.3 but it happened in previous versions and I'm running OSX Yosemite.

My projects use tabs and it triggers almost every save, even if it hasn't converted anything (I.e. everything is already tabs). I've noticed it in both js and scss files.

lewishowles commented 9 years ago

Oh and yes, v1.0.0 is correct.

MiguelCastillo commented 9 years ago

Do you think it would be possible to share the file with me? Also, how many spaces per tab do you have Brackets configured to?

lewishowles commented 9 years ago

Typical bug, as soon as you go to show someone else, it doesn't happen.

I had uninstalled it because it made Brackets unusable as it was happening nigh on every save in every file. I just re-installed (which I had tried previously, on more than one occasion) but now I can't actually make it bug out in any of the files I've seen it happen before. I've even tried changing some of the indentation to spaces to trigger actual changes by wsSanitizer (which brought up a minor bug I will file separately).

I'm on my home machine rather than my work machine at the moment, but each is running the same version of Brackets and OSX.

If I see it happen again, in addition to sending you the particular file, is there anything else you would want me to tell you about the machine?

joepie91 commented 9 years ago

@MiguelCastillo I could share the file with you, but this specific file is probably not one I can share publicly on here... can I e-mail it to you?

I tried to reproduce with a mock file:

function(arg) {
    asdfasdf;
}

... but could not reproduce it this way.

EDIT: That mock file uses tabs, by the way. Github converts it to spaces for some reason.

MiguelCastillo commented 9 years ago

@joepie91 Yeah of course, email it to me is fine. manchagnu@gmail.com. I really appreciate it :)

MiguelCastillo commented 9 years ago

@lewishowles Yeah it sucks I can't reproduce it... :/ Yeah if you can email me the file and how many spaces per tab you configured brackets to, that would be really helpful.

I am thinking there are jsdoc type of comments that has a white space in there... And that's mixed with tabs, so my logic to detect tab/space mixture is triggered. The logic is correct in detecting that, but it seems like that's not the behavior we want. I am reworking some of the logic right now... But files to test would be awesome! :)

MiguelCastillo commented 9 years ago

@lewishowles @joepie91 Hey folks, I have added a few lines for logging what's going on. It's https://github.com/MiguelCastillo/Brackets-wsSanitizer/commit/60fa9112c20bab9279a2dac6c6d3416e1803138a

Do you think you can apply those changes to your installed extension to help me debug this issue? I am really at a loss here because I am unable to reproduce the issue :-/

If you reproduce the issue, can you paste the console.log here? Or email it to me if there is sensitive information in the trace.

Let me know if you need help applying those changes.

joepie91 commented 9 years ago

selection_252

joepie91 commented 9 years ago

That's from a single save, I should note. It just keeps going endlessly.

MiguelCastillo commented 9 years ago

@joepie91 Well, that trace does not make any sense... "Trigger save" shows that doc.__saving is set to true... And then "Skip save" shows it as undefined. The only way that's possible is if the doc is not the same instance, or the setTimeout to save the document isn't really working and runs the code synchronously.

Can you set the setTimeout to maybe 100? e.g.

      setTimeout(function() {
        CommandManager.execute(Commands.FILE_SAVE, {doc: doc})
          .always(function() {
            delete doc.__saving;
          });
      }, 100);
joepie91 commented 9 years ago

I've gone a little further...

  function runSanitizer(evt, doc) {
    var rnd = Math.floor(Math.random() * 1000);
    console.log("1. ====> Skip save", rnd, doc.__saving);
    if (doc.__saving) {
      console.log("1.5 =====> Returning early...", rnd);
      return;
    }
    console.log("2. =====> Still running", rnd, doc.__saving);
    doc.__saving = true;
    console.log("3. =====> Saving now set to ", rnd, doc.__saving);
    doc.batchOperation(function () {
      console.log("4. =====> Saving in batch set to ", rnd, doc.__saving);
      var oldText = doc.getText();
      sanitize(doc);
      var newText = doc.getText();
      console.log("5. ====> Trigger save", rnd, oldText === newText, doc.__saving);

      console.log("6. ====> Setting timeout", rnd);
      setTimeout(function() {
        console.log("7. ====> Timeout triggered", rnd);
        CommandManager.execute(Commands.FILE_SAVE, {doc: doc})
          .always(function() {
            console.log("8. =====> Deleting 'saving' flag", rnd);
            delete doc.__saving;
          });
      }, 2000);
    });
  }

Output:

selection_253

Looks like this isn't the issue you fixed - there's no race condition, everything is called only once and perfectly in order (per the randomly generated number). But once the document has been saved, it triggers a re-save for some reason.

EDIT: Note also how the early return never even happens. Evidently the issue is elsewhere :)

MiguelCastillo commented 9 years ago

@joepie91 Yeah that sequence is wrong. Between step 7 and 8 I should have seen step 1 and 1.5 get logged, which happens because of the save operation I am triggering is on next tick. That's exactly why you are getting stuck in a loop. So it seems that either setTimeout isn't working at all, or CommandManager.execute(Commands.FILE_SAVE, {doc: doc}) is not running on next tick. Both cases seem really odd, but it's gotta be one of them.

Below is what my stack trace looks like.

main.js:57 1. ====> Skip save 404 undefined
main.js:62 2. =====> Still running 404 undefined
main.js:64 3. =====> Saving now set to  404 true
main.js:66 4. =====> Saving in batch set to  404 true
main.js:70 5. ====> Trigger save 404 false true
main.js:72 6. ====> Setting timeout 404
main.js:74 7. ====> Timeout triggered 404
main.js:57 1. ====> Skip save 153 true
main.js:59 1.5 =====> Returning early... 153
main.js:77 8. =====> Deleting 'saving' flag 404

I have pushed new changes with your logging, an extra timeout, and logging the actual timeout value of the first setTimeout. Do you think you can run those changes and paste the trace again, please? That trace is really helpful. Thank you! :) https://github.com/MiguelCastillo/Brackets-wsSanitizer/commit/58c951e1d1a6e4196a7dc622ef4bd4ab37ea094b

equinox commented 9 years ago

I actually just got this after accepting the new UI's request to sanitize my file (I then saved). It looked to me like the rest of Brackets' interface was flashing, the code folding was blinking on and off. I'll try and get a way to reproduce.

it goes from this to this constantly.

MiguelCastillo commented 9 years ago

Hi folks. I have released a new version and I have changed a bit of the logic around saving... Added an option to disable autosave so that people are not completely stuck. Do folks think you can give this a try? it's already pushed to the registry. Thanks!!