Menu

#2504 Report and Fix for Spurious Error Message Checking Reload on Untitled Files

Bug
open-fixed
nobody
5
4 days ago
7 days ago
No

SciTE will display the spurious error 'The file '<path to working directory>' has been deleted' in a message box after running a custom Lua function from the Tool menu if:

  1. load.on.activate is set to 1.
  2. The active tab contains an Untitled file.

Example Lua function:

function sort_text()
  local sel = editor:GetSelText()
  if #sel == 0 then return end
  local eol = string.match(sel, "\n$")
  local buf = lines(sel)
  --table.foreach(buf, print) --used for debugging
  table.sort(buf)
  local out = table.concat(buf, "\n")
  if eol then out = out.."\n" end
  editor:ReplaceSel(out)
end

Tool menu entry:

command.name.1.*=Sort Lines
command.subsystem.1.*=3
command.1.*=sort_text
command.save.before.1.*=2

Patch is attached that modifies CheckReload() to do nothing if the current filePath is an Untitled file.

1 Attachments

Discussion

  • Neil Hodgson

    Neil Hodgson - 6 days ago

    This does not occur for me and the path through the code should not be possible.

    newModTime will be 0 because there is a check for untitled in FilePath::ModifiedTimethat returns 0. Then there must be a non-0 value in CurrentBuffer()->fileModTime which shouldn't be possible since it is for an untitled buffer. Possibly something more complex is occurring.

    The above example is missing a lines function.

     
  • Mark W. Gabby-Li

    Here's the lines() function:

    function lines(str)
      local t = {}
      local i, lstr = 1, #str
      while i <= lstr do
        local x, y = string.find(str, "\r?\n", i)
        if x then t[#t + 1] = string.sub(str, i, x - 1)
        else break
        end
        i = y + 1
      end
      if i <= lstr then t[#t + 1] = string.sub(str, i) end
      return t
    end
    

    I tested with and without my change, and it definitely made the error dialog go away. I've attached an example of the error dialog for reference.

     
  • Mark W. Gabby-Li

    I added some logs, and what's happening is command.is.filter is being read as set by JobMode::JobMode(), so isFilter is set. Is that the default? I did not set it in my tool.

    That causes SciTEBase::ToolsMenu() to set CurrentBuffer()->fileModTime to -1, which meets all the criteria for the conditional to hit for the error message on an Untitled buffer.

     
  • Neil Hodgson

    Neil Hodgson - 6 days ago

    Check for overlapping command patterns. If there are two patterns like *.java and *.cpp specifying properties, the priority is not obvious. The standard properties only specify a few filter properties for *.sol and command.is.filter.0.$(file.patterns.cpp) which is for command 0 so shouldn't interfere with your command 1. As well as command.is.filter, command.mode may set the filter state.

    The filter code could be improved as the time hack to force reload isn't great.

     
  • Mark W. Gabby-Li

    Sure, but that still means that a command that is set as a filter (not that I know what that means) will produce this spurious error message?

    Also perhaps the code that job mode is calling is assuming that all files have extensions, which could be what is causing some of the unpredictable behavior? I'd have to dig into that more though, ideally with a debugger.

    (never mind about the -1 mod time comment, I think I misunderstood.)

    I will look at my properties later, I don't have them on hand right at the moment. Thank you for your time thus far!

     

    Last edit: Mark W. Gabby-Li 6 days ago
  • Mark W. Gabby-Li

    Digging into my properties, I don't see any filter settings at all for any commands, nor any use of command.mode. I've attached all the options files and my Lua startup script to this comment. Note that I'm on Windows and I've seen this behavior on the latest in hg as of my report.

    When the call is made to get the filter status of the command in the JobMode constructor, propName is command.is.filter.1., and fileNameExt is empty.

     
  • Neil Hodgson

    Neil Hodgson - 5 days ago

    Wasn't able to reproduce with those files.

    It's better to find the base cause of this bug instead of recovering in CheckReload as the bug may cause other problems.

    When the call is made to get the filter status of the command in the JobMode constructor, propName is command.is.filter.1., and fileNameExt is empty.

    The main things I'm imaging could be wrong are unexpected command properties or incorrect wildcard matching. There are other settings that include "filter" so a spurious match may be possible.

    Is it producing a non-empty modeVal in JobMode::JobMode and what is its value if it is non-empty?

    In the props.GetWild for "command.is.filter.", which return statement is hit and how many times did the main while (psf) { loop iterate? That will show which property set was responsible. If its the MatchWildSet that succeeds, what is the it->first and keyFile.

    The user properties includes properties.directory.enable=1 so check what is in the directory options file and also local options.

     
  • Mark W. Gabby-Li

    Found it!

    html.properties in C:\ProgramData\SciTE\. The broken property is in a Windows platform block! This is why it was happening for me but not you, you must be on a different platform (I was also not able to replicate it on Linux, so I just booted into Windows and found the error):

    if PLAT_WIN
    [...]
        command.is.filter.1.*=1
    
     

    Last edit: Mark W. Gabby-Li 5 days ago
  • Neil Hodgson

    Neil Hodgson - 5 days ago

    That line isn't in the distributed html.properties (sourceforge.net). I have some recollection of setting up HTML Tidy to reformat HTML files so it may be in some other version of html.properties.

    With that cleared up, it should be OK to stop the problem for untitled files by avoiding the decrement for invalid modification times. While there may be some benefit to running a filter like HTML Tidy on an untitled buffer, there would be the hassle of creating a temporary file and making sure to remove it later. The user can save the buffer into a real file if they want to do something with it.

    diff -r 981c4a52abe7 src/SciTEBase.h
    --- a/src/SciTEBase.h   Tue Mar 31 09:39:25 2026 +1100
    +++ b/src/SciTEBase.h   Wed Apr 01 15:16:45 2026 +1100
    @@ -123,6 +123,7 @@
        void SetTimeFromFile();
    
        void DocumentModified() noexcept;
    
    +   void WantReload() noexcept;
        bool NeedsSave(int delayBeforeSave) const noexcept;
    
        void CompleteLoading() noexcept;
    diff -r 981c4a52abe7 src/SciTEBuffers.cxx
    --- a/src/SciTEBuffers.cxx  Tue Mar 31 09:39:25 2026 +1100
    +++ b/src/SciTEBuffers.cxx  Wed Apr 01 15:16:45 2026 +1100
    @@ -102,6 +102,14 @@
        documentModTime = time(nullptr);
     }
    
    +void Buffer::WantReload() noexcept {
    
    +   if (fileModTime) {
    +       // Signal that the file should be reloaded by decreasing its modification time so file on
    +       // disk appears newer. Only do this for a valid modification time.
    +       fileModTime--;
    +   }
    +}
    +
     bool Buffer::NeedsSave(int delayBeforeSave) const  noexcept {
        const time_t now = time(nullptr);
        return now && documentModTime && isDirty && !pFileWorker && (now-documentModTime > delayBeforeSave) && !file.IsUntitled() && !failedSave;
    @@ -1576,7 +1584,7 @@
                return;
            if (jobMode.saveBefore == 2 || (jobMode.saveBefore == 1 && (!(CurrentBuffer()->isDirty) || Save())) || SaveIfUnsure() != SaveResult::cancelled) {
                if (jobMode.isFilter)
    -               CurrentBuffer()->fileModTime -= 1;
    +               CurrentBuffer()->WantReload();
                if (jobMode.jobType == JobSubsystem::immediate) {
                    if (extender) {
                        extender->OnExecute(command.c_str());
    
     
  • Mark W. Gabby-Li

    Thanks. For full clarity, I believe my Windows installs came from the old "SciTE for Windows" installers, which may have had different versions of the property files?

    I see the Windows installers are no longer available. I seem to remember they were provided by a third party rather than the project itself? Perhaps there was some mistake when packaging them and they included user-customized property file by accident, or perhaps they had intentional customizations.

     
  • Neil Hodgson

    Neil Hodgson - 4 days ago

    Committed the above code with [1c0de1].

    The installer appears to have been discontinued by its author. The customizations were part of the purpose of that project.

     

    Related

    Commit: [1c0de1]

  • Neil Hodgson

    Neil Hodgson - 4 days ago
    • labels: --> scite, reload, command, filter
    • status: open --> open-fixed
     

Log in to post a comment.

MongoDB Logo MongoDB