Community
    • 登入

    Perl subroutine calltips - with PythonScript

    已排程 已置頂 已鎖定 已移動 General Discussion
    52 貼文 4 Posters 7.8k 瀏覽
    正在載入更多貼文
    • 從舊到新
    • 從新到舊
    • 最多點贊
    回覆
    • 在新貼文中回覆
    登入後回覆
    此主題已被刪除。只有擁有主題管理權限的使用者可以查看。
    • Michael VincentM
      Michael Vincent @PeterJones
      最後由 編輯

      @PeterJones said in Perl subroutine calltips - with PythonScript:

      (Now you just need to come up with the logic to search all the included library modules as well… or, um, maybe not.)

      I thought I read somewhere: “only perl can parse Perl”. I originally wrote this in PerlScript since it was more familiar to me and then just had my PythonScript so a subprocess(['perl', 'perl_ide.pl' ... but that was awful slow and launched a CMD window - so I ported the whole thing to Python.

      I’ve been looking at Perl Language Servers but that would require a Notepad++Language Server client (the topic in the post I linked to at the beginning). One mentions integrating plsense which looks amazing!

      I liked @Ekopalypse approach of this lightweight way to go with a scripting plugin. I have my cTags plugin helping with autocomplete across my Perl scripts in the same hierarchy and NppEventExec can be set to perl -c on file save. Not sure what else we can do to parse Perl with Python to make this “Perl IDE” better, but certainly open to suggestions!

      Cheers.

      EkopalypseE 1 條回覆 最後回覆 回覆 引用 2
      • EkopalypseE
        Ekopalypse @Michael Vincent
        最後由 編輯

        @Michael-Vincent

        does perl, itself, has a feature of parsing. By that I mean builtin not by
        using perl -module.pm script.pm

        PeterJonesP Michael VincentM 2 條回覆 最後回覆 回覆 引用 1
        • PeterJonesP
          PeterJones @Ekopalypse
          最後由 PeterJones 編輯

          @Ekopalypse ,

          “builtin” – not quite; perl -c does a compile check, but doesn’t give you the full parse…

          There is the CORE module B::Deparse, which runs as perl -MO=Deparse script.pl, which comes closer – though I’ve never used it except when replicating experiments shown by perlmonks experts, so I don’t really know how to use it. (CORE is defined as the set of modules that ship with Perl, by default, and are normally assumed to be present; though there are minimalist distributions of Perl which don’t include all of CORE.)

          But with Perl, you can do some pretty powerful stuff (like define an anonymous subroutine, then manually assign it to a slot in any namespace, so that from the user’s point of view, there is no difference between that and a subroutine that had been defined by a traditional sub name { ... } block. I don’t know how well Deparse works with those.

          The thought behind “only perl can parse Perl” is that, by Perl’s very nature, if you create an executable that’s capable of parsing any arbitrary correct Perl code, that executable is effectively an implementation of the perl executable.

          EkopalypseE 1 條回覆 最後回覆 回覆 引用 2
          • Michael VincentM
            Michael Vincent @Ekopalypse
            最後由 Michael Vincent 編輯

            @Ekopalypse said in Perl subroutine calltips - with PythonScript:

            does perl, itself, has a feature of parsing

            @PeterJones probably knows better than I (EDIT: HE ALSO TYPES FASTER!!!) but I don’t think so. perl -c will “compile / check” to make sure your code is valid without actually running it. That would be the equivalent to maybe the “lint” feature in your Python IDE script.

            To actually parse the Perl and return methods for objects, you’d need something like plsense modified to work in this environment. There is also Perl::LanguageServer which seems to be the most complete Perl Language Server but note it does not work on Windows (so says the README) and it requires a Language Server Client - NppLSP - but as discussed, it’s very alpha.

            Cheers.

            1 條回覆 最後回覆 回覆 引用 2
            • EkopalypseE
              Ekopalypse @PeterJones
              最後由 Ekopalypse 編輯

              i was thinking - can we use perl.dll in some way?
              It seems to export a lot of stuff.

              1 條回覆 最後回覆 回覆 引用 2
              • EkopalypseE
                Ekopalypse
                最後由 編輯

                it has

                ...
                 806  325 00023D20 Perl_parse_arithexpr
                 807  326 00023D90 Perl_parse_barestmt
                 808  327 00023D60 Perl_parse_block
                 809  328 00023D50 Perl_parse_fullexpr
                 810  329 00024130 Perl_parse_fullstmt
                 811  32A 00023DC0 Perl_parse_label
                 812  32B 00023D40 Perl_parse_listexpr
                 813  32C 00024160 Perl_parse_stmtseq
                 814  32D 00023D30 Perl_parse_termexpr
                 815  32E 00039A50 Perl_parse_uniprop_string
                 816  32F 0009B3C0 Perl_parser_dup
                ...
                
                EkopalypseE 1 條回覆 最後回覆 回覆 引用 1
                • EkopalypseE
                  Ekopalypse @Ekopalypse
                  最後由 編輯

                  @Ekopalypse

                  there is even an exported function RunPerl

                  EXTERN_C DllExport int
                  RunPerl(int argc, char **argv, char **env)
                  {
                      int exitstatus;
                      PerlInterpreter *my_perl, *new_perl = NULL;
                      bool use_environ = (env == environ);
                  
                  #ifdef PERL_GLOBAL_STRUCT
                  #define PERLVAR(prefix,var,type) /**/
                  #define PERLVARA(prefix,var,type) /**/
                  #define PERLVARI(prefix,var,type,init) PL_Vars.prefix##var = init;
                  #define PERLVARIC(prefix,var,type,init) PL_Vars.prefix##var = init;
                  #include "perlvars.h"
                  #undef PERLVAR
                  #undef PERLVARA
                  #undef PERLVARI
                  #undef PERLVARIC
                  #endif
                  
                      PERL_SYS_INIT(&argc,&argv);
                  
                      if (!(my_perl = perl_alloc()))
                  	return (1);
                      perl_construct(my_perl);
                      PL_perl_destruct_level = 0;
                  
                      /* PERL_SYS_INIT() may update the environment, e.g. via ansify_path().
                       * This may reallocate the RTL environment block. Therefore we need
                       * to make sure that `env` continues to have the same value as `environ`
                       * if we have been called this way.  If we have been called with any
                       * other value for `env` then all environment munging by PERL_SYS_INIT()
                       * will be lost again.
                       */
                      if (use_environ)
                          env = environ;
                  
                      if (!perl_parse(my_perl, xs_init, argc, argv, env)) {
                  #if defined(TOP_CLONE) && defined(USE_ITHREADS)		/* XXXXXX testing */
                  	new_perl = perl_clone(my_perl, 1);
                  	(void) perl_run(new_perl);
                  	PERL_SET_THX(my_perl);
                  #else
                  	(void) perl_run(my_perl);
                  #endif
                      }
                  
                      exitstatus = perl_destruct(my_perl);
                      perl_free(my_perl);
                  #ifdef USE_ITHREADS
                      if (new_perl) {
                  	PERL_SET_THX(new_perl);
                  	exitstatus = perl_destruct(new_perl);
                  	perl_free(new_perl);
                      }
                  #endif
                  
                      PERL_SYS_TERM();
                  
                      return (exitstatus);
                  }
                  
                  PeterJonesP 1 條回覆 最後回覆 回覆 引用 1
                  • PeterJonesP
                    PeterJones @Ekopalypse
                    最後由 編輯

                    @Ekopalypse ,

                    I don’t know the guts (I was going to say “very well”, but that would be understatement; I think the unqualified comes closest to the truth), but perldoc perlembed shows how to embed the perl interpreter into an application, and takes a bit about perl_parse and perl_run.

                    But I wouldn’t know where to begin on using those functions, or even the output of -MO=Deparse, and implementing a stronger version of what @Michael-Vincent has shown. And even if I did, I already have my huge project of the Win32::Mechanize::NotepadPlusPlus which isn’t quite to where I want it, and the PerlScript plugin wrapper that I haven’t even started writing yet – and I cannot take on another big project until I’ve got those to a reasonably-functional level.

                    EkopalypseE 1 條回覆 最後回覆 回覆 引用 1
                    • EkopalypseE
                      Ekopalypse @PeterJones
                      最後由 編輯

                      @PeterJones

                      no problem … I was curious and played already a bit with it.
                      If I’m right, then 5 lines of pythonscript might give you an embedded perl.

                      PeterJonesP 1 條回覆 最後回覆 回覆 引用 1
                      • PeterJonesP
                        PeterJones @Ekopalypse
                        最後由 編輯

                        @Ekopalypse said in Perl subroutine calltips - with PythonScript:

                        5 lines of pythonscript might give you an embedded perl.

                        Oh, the irony. :-)

                        EkopalypseE 2 條回覆 最後回覆 回覆 引用 1
                        • EkopalypseE
                          Ekopalypse @PeterJones
                          最後由 編輯

                          @PeterJones

                          :-D

                          this seems to do something, not sure what but it doesn’t crash my npp … so … still crossing fingers ;-)

                          from ctypes import CDLL, POINTER, c_int, c_char_p
                          
                          perllib = CDLL(r'd:\perl\bin\perl531.dll')
                          
                          ["-le", "print 'something \"with\" quotes';"]
                          
                          perllib.RunPerl.restype = c_int
                          perllib.RunPerl.argtypes = c_int, POINTER(c_char_p), POINTER(c_char_p)
                          args = (c_char_p * 2)(b"-le", b"print 'something \"with\" quotes';")
                          print(perllib.RunPerl(len(args),args, None))
                          
                          1 條回覆 最後回覆 回覆 引用 2
                          • EkopalypseE
                            Ekopalypse @PeterJones
                            最後由 Ekopalypse 編輯

                            @PeterJones

                            can you give me a qiuck “Win32::Mechanize::NotepadPlusPlus for dummies äh ekopalypses” to open a new npp buffer?

                            PeterJonesP 1 條回覆 最後回覆 回覆 引用 1
                            • PeterJonesP
                              PeterJones @Ekopalypse
                              最後由 編輯

                              @Ekopalypse ,

                              From the command line, to just open a new file tab:

                              perl -le "use Win32::Mechanize::NotepadPlusPlus qw/:main/; notepad->newFile();"
                              

                              If you want to call a script.pl instead,

                              use Win32::Mechanize::NotepadPlusPlus qw/:main/; 
                              notepad->newFile();
                              

                              But that assumes that perl has the right @INC (include library paths) to find Win32::Mechanize::NotepadPlusPlus.

                              EkopalypseE 1 條回覆 最後回覆 回覆 引用 2
                              • EkopalypseE
                                Ekopalypse @PeterJones
                                最後由 編輯

                                @PeterJones

                                D:\perl\bin>perl D:\temp\perl\Win32-Mechanize-NotepadPlusPlus-0.005\Makefile.PL
                                Could not open 'lib/Win32/Mechanize/NotepadPlusPlus.pm': No such file or directory at D:/perl/lib/ExtUtils/MM_Unix.pm line 2973.
                                

                                Now you know why I said “… for ekopalypses” ;-)

                                PeterJonesP 2 條回覆 最後回覆 回覆 引用 1
                                • EkopalypseE
                                  Ekopalypse
                                  最後由 編輯

                                  hah, it is the other way around … from within the source call perl …

                                  1 條回覆 最後回覆 回覆 引用 1
                                  • PeterJonesP
                                    PeterJones @Ekopalypse
                                    最後由 編輯

                                    @Ekopalypse said in Perl subroutine calltips - with PythonScript:

                                    @PeterJones

                                    D:\perl\bin>perl D:\temp\perl\Win32-Mechanize-NotepadPlusPlus-0.005\Makefile.PL
                                    Could not open 'lib/Win32/Mechanize/NotepadPlusPlus.pm': No such file or directory at D:/perl/lib/ExtUtils/MM_Unix.pm line 2973.
                                    

                                    For the installation, you need to be in the D:\temp\perl\Win32-Mechanize-NotepadPlusPlus-0.005\ directory, and run d:\perl\bin\perl Makefile.PL instead: you need to be in the same directory as the Makefile.PL, so that the relative paths are all correct.

                                    EkopalypseE 1 條回覆 最後回覆 回覆 引用 2
                                    • EkopalypseE
                                      Ekopalypse @PeterJones
                                      最後由 編輯

                                      @PeterJones

                                      and then I used nmake to create the pm’s.
                                      I’ve copied the resulting Win32 to …/perl/lib/
                                      but now I get Can't locate Win32/API.pm in @INC (you may need to install the Win32::API module) (@INC contains: d:/perl/site/lib d:/perl/lib) at d:/perl/lib/Win32/Mechanize/NotepadPlusPlus/Notepad.pm line 9.

                                      1 條回覆 最後回覆 回覆 引用 1
                                      • PeterJonesP
                                        PeterJones @Ekopalypse
                                        最後由 編輯

                                        @Ekopalypse ,

                                        The other thing I realized: you probably won’t have all the prerequisite modules installed. I normally use the cpanm utility, which distributes with strawberry perl, and that automatically downloads and installs prereqs before the module you’re trying to install. Without such a tool (and if you built your own perl, which I think you did to get the DLL), I don’t know that you have that.

                                        I think the make process will tell you what prereqs you’re missing … but it’s been a long time since I’ve done a complicated manual install of a module.

                                        Oh, yep, there, you posted the error while I was typing. You’re going to have to install at least Win32::API first… doing that manually is a pain.

                                        When you built your own perl, did you at least get cpan, if not cpanm? I think one or both would be in the same directory as perl.exe… if you have cpanm, just do cpanm Win32::Mechanize::NotepadPlusPlus, and everything should work. If you have just cpan, I forget whether it handles prereqs; try cpan Win32::Mechanize::NotepadPlusPlus; if that’s not sufficient, do the missing prereqs one at a time with the cpan client. If you have neither… um… That’s going to be tough.

                                        Michael VincentM 1 條回覆 最後回覆 回覆 引用 1
                                        • Michael VincentM
                                          Michael Vincent @PeterJones
                                          最後由 編輯

                                          @PeterJones said in Perl subroutine calltips - with PythonScript:

                                          If you have just cpan, I forget whether it handles prereqs

                                          I believe it does - I normally just use CPAN and it fetches what I need to build.

                                          Cheers.

                                          1 條回覆 最後回覆 回覆 引用 1
                                          • EkopalypseE
                                            Ekopalypse
                                            最後由 編輯

                                            I have cpan and it keeps installing stuff - did I choose to install the world??

                                            1 條回覆 最後回覆 回覆 引用 0
                                            • 第一個貼文
                                              最後的貼文
                                            The Community of users of the Notepad++ text editor.
                                            Powered by NodeBB | Contributors