Notepad++ Python Script - Find files containing string at specific line



  • I need to write a Python script for Notepad++ (using http://npppythonscript.sourceforge.net/), which will find PHP files if their next-to-last line contains ?> tag.

    In other words, it should find files like:

    <?php
    whatever_goes_here
    ?>
    ... 
    

    and NOT find files like:

    <?php
    whatever_goes_here
    ?>
    

    So I wrote:

    import os;
    import sys;
    filePathSrc="C:\\Temp\\some_directory"
    for root, dirs, files in os.walk(filePathSrc):
        for fn in files:
          if fn[-4:] == '.php':
            notepad.open(root + "\\" + fn)
            endposition=editor.getLineCount()
            endposition=endposition-1
            editor.gotoLine(endposition)
            editor.findText('SCFIND_WHOLEWORD', 0, 999999999999999999999999, '?>')
    

    I’m pretty sure editor.findText is wrong (didn’t know what to enter as end position, so just entered many 9s). Anyways, how should I proceed further to check if next-to-last line contains ?> tag?

    The need of such a script is simple: I need to see all the PHP files that contain closing tag at the end of file, so I can remove ths tag if file is pure PHP (as per http://www.php-fig.org/psr/psr-2/#general)



  • @toxpal

    So first things first: you can get rid of the really big number of 9’s and just do it correctly: substitute editor.getTextlength()

    Secondly, I rarely use editor.findText() but in the single case in my set of scripts where I do, my first argument to it is FINDOPTION.REGEXP. Note: I prefer editor.research().

    Third, I might be tempted to search for the following regular expression in your case: (?s)<\?php\r\n.+?\?>\r\n.+. This seems to match your criterion of only matching your closing tag (?>) with something on the next line.

    These are just some general hints in the direction I believe might prove helpful to your script writing. Hope it helps somewhat.



  • @toxpal said:

    I need to write a Python script for Notepad++ (using http://npppythonscript.sourceforge.net/), which will find PHP files if their next-to-last line contains ?> tag.

    In other words, it should find files like:

    <?php
    whatever_goes_here
    ?>
    ... 
    

    and NOT find files like:

    <?php
    whatever_goes_here
    ?>
    

    So I wrote:

    import os;
    import sys;
    filePathSrc="C:\\Temp\\some_directory"
    for root, dirs, files in os.walk(filePathSrc):
        for fn in files:
          if fn[-4:] == '.php':
            notepad.open(root + "\\" + fn)
            endposition=editor.getLineCount()
            endposition=endposition-1
            editor.gotoLine(endposition)
            editor.findText('SCFIND_WHOLEWORD', 0, 999999999999999999999999, '?>')
    

    I’m pretty sure editor.findText is wrong (didn’t know what to enter as end position, so just entered many 9s). Anyways, how should I proceed further to check if next-to-last line contains ?> tag?

    The need of such a script is simple: I need to see all the PHP files that contain closing tag at the end of file, so I can remove ths tag if file is pure PHP (as per http://www.php-fig.org/psr/psr-2/#general)



  • @Scott-Sumner thanks for your suggestions. I will check editor.getTextlength(), but searching with regex won’t suit my needs, because I only need to find files that contain closing PHP tag at exactly next-to-last line and ignore all the files that contain such a tag in other line(s).



  • @toxpal

    I fail to see how a regex in the call to editor.findText() or editor.research() can’t help solve your problem.

    Okay, so we can tighten up the regex (which means making it longer, ironically) to match your description better:
    (?s)<\?php\r\n.+?\?>\r\n[^\r\n]+(?:\r\n)?\z

    …but that doesn’t help aid my understanding of why you think it can’t benefit your situation.



  • I’ll give it a try, and let you know how it works.



  • Tried using regex, but script does nothing (not sure if it’s regex or script’s fault):

    import os;
    import sys;
    filePathSrc="C:\\Temp\\some_directory"
    for root, dirs, files in os.walk(filePathSrc):
        for fn in files:
          if fn[-4:] == '.php':
            notepad.open(root + "\\" + fn)
            textlength=editor.getTextlength()
            editor.findText('SCFIND_REGEXP', 0, textlength, '(?s)<\?php\r\n.+?\?>\r\n[^\r\n]+(?:\r\n)?\z')


  • Update: pretty sure it’s scripts fault because even if I write such a simple search function, it does NOT work:

    import os;
    import sys;
    filePathSrc="C:\\Temp\\some_directory"
    for root, dirs, files in os.walk(filePathSrc):
        for fn in files:
          if fn[-4:] == '.php':
            notepad.open(root + "\\" + fn)
            textlength=editor.getTextlength()
            editor.findText('SCFIND_WHOLEWORD', 0, textlength, '<html>')
    

    What am I missing here?



  • @toxpal

    Perhaps “<” and “>” are not considered parts of a word, so SCIFIND_WHOLEWORD fails given your “word”?

    Maybe try SCIFIND_REGEXP with a regex having no special characters (like “html”) to find out?



  • Tried:

    import os;
    import sys;
    filePathSrc="C:\\Temp\\some_directory"
    for root, dirs, files in os.walk(filePathSrc):
        for fn in files:
          if fn[-4:] == '.php':
            notepad.open(root + "\\" + fn)
            textlength=editor.getTextlength()
            editor.findText('SCFIND_REGEXP', 0, textlength, 'html')
    

    Also does nothing…



  • @toxpal

    As my second point in my first post in this thread, I pointed out that the first argument to the editor.findText() function is NOT a string. Continuing to code it as if it is a string will get you nowhere. I think that if you look at the Pythonscript console window after running the script you will see that your script isn’t doing “nothing”, it’s giving you errors. For me it gives this error when I (intentionally) specify a string as the first argument to editor.findText():

    f = editor.findText('SCFIND_REGEXP', 0, editor.getTextLength(), 't')
    <class 'Boost.Python.ArgumentError'>:  Python argument types in
    Editor.findText(Editor, str, int, int, str)
    did not match C++ signature:
    findText(class NppPythonScript::ScintillaWrapper {lvalue}, int flags, int start, int end, class boost::python::api::object ft)
    

    The complete set of proper values for the first argument is found in the help docs for Pythonscript:

    class FINDOPTION :
    FINDOPTION.WHOLEWORD 
    FINDOPTION.MATCHCASE 
    FINDOPTION.WORDSTART 
    FINDOPTION.REGEXP 
    FINDOPTION.POSIX


  • Thank you for your efforts. I’m totally new to Python, so I’m having troubles with it.

    So I modified script:

    import os;
    import sys;
    filePathSrc="C:\\Temp\\some_directory"
    for root, dirs, files in os.walk(filePathSrc):
        for fn in files:
          if fn[-4:] == '.php':
            notepad.open(root + "\\" + fn)
            console.write(root + "\\" + fn + "\r\n")
            end_position=editor.getTextlength()
            editor.findText(FINDOPTION.MATCHCASE, 0, end_position, "<html>")
    

    Now console returns error AttributeError: 'Editor' object has no attribute 'getTextlength'

    Changing getTextlength to getLength removes all the errors in console, and it only displays a message that PHP file was opened. However, it still doesn’t find any string



  • @toxpal

    OK, so you have to read the documentation to see how these “editor” functions work. See Plugins -> Pythonscript -> Context-Help.

    If you do this, you will see that editor.findText() returns a value indicating where a match did (or didn’t) occur.

    Does this make sense?

    Same thing applies to editor.getTextLength()…except in that case you actually have to spell it correctly (hint: case matters)…


Log in to reply