Menu

Guide: Using NppExec to compile any sources

NppExec
DV
2008-11-01
2013-05-21
  • DV

    DV - 2008-11-01

    Guide: Using NppExec to compile sources with associated compilers

    As a Notepad++ user, did you ever think about ability to compile your source
    file with its associated compiler in a single action?
    You may use the NppExec plugin to perform certain actions on your files, but
    what about the automatization? What if you want your .c files to be compiled
    with tcc, .cpp files to be compiled with g++ and .awk files to be interpretted
    with gawk automatically, without explicit call to required compiler or
    interpretter? Is it possible?
    Yes, NppExec ALREADY allows you to do this. All you need is some imagination
    and several things to do. And I'm about to tell what is needed.

    Let's begin with several theoretical questions.
    At first, how can NppExec understand which compiler/interpretter is required
    by your current source file? NppExec is not a compiler, it does not have
    any information about your file and does not know what to do with it.
    Moreover, Notepad++ itself is not such IDE as Visual C++ Express or Dev-C++,
    it does not include any compiler and also does not know what to do with your
    source file.
    So, the only way to compile your source file with required compiler is to tell
    Notepad++ (to tell NppExec in our case) _which_ compiler to use and _how_ to
    use it.
    This is the solution which you may use already - explicit usage of certain
    compiler/interpretter with certain source file. For example, you may want to
    compile and run your .c source file with tcc. A simple NppExec's script can
    be created for this purpose:

      "C:\tools\tcc\tcc.exe" "$(FULL_CURRENT_PATH)" -run
     
    The full path "C:\tools\tcc\tcc.exe" specifies a path to required compiler;
    Notepad++'es environment variable "$(FULL_CURRENT_PATH)" specifies full path
    name to your current source file; and "-run" in tcc's command line means
    "run compiled source". The full path was given in quotes, because, in general,
    it can contain spaces.
    Now, we are talking about NppExec's script. It assumes the script has been
    created and saved with some name which identified that script. If you are
    not sure about NppExec's script creation & saving, let me guide you.

    To create & save some NppExec's script, do the following:
    1) Open NppExec's "Execute..." window: press the hotkey (F6 by default)
       or select (main menu) Plugins -> NppExec -> Execute...
    2) Type the text of your script in the "Execute..." window. For example:

         "C:\tools\tcc\tcc.exe" "$(FULL_CURRENT_PATH)" -run
        
    3) Save this new script: press the "Save..." button, type your script name
       (for example, type "run@.c") and press Save.

    Now you can compile & run any single .c file opened in Notepad++. To do it,
    press F6 (default hotkey for the "Execute..." window), select "run@.c" in
    the combo-box and press OK.
    You can press Ctrl+F6 (by default) to execute the same script again without
    showing the "Execute..." window.

    As you can see, currently you have to call the "run@.c" script explicitly
    in order to compile & run your .c source file. Thus, to compile & run
    another source file (.cpp, .asm, .php, .lua, ...) you also have to call
    corresponding script explicitly. [The last sentence assumes you have created
    separate scripts for every language you use (.cpp, .asm, .php, .lua, ...)]
    However, we don't want to call required script explicitly. We want NppExec
    to call the "run@.c" script for a .c file and call different script required
    for different (.cpp, .asm, .php, .lua, ...) file automatically.
    So, a question: how can we do it?
    The first part of the answer is in your source file's extension. There is
    such environment varible as $(EXT_PART) which contains the extension of
    current file opened in Notepad++.
    The second part of the answer is in NppExec's internal command NPP_EXEC.
    As you probably know already, this command expects an existing script name
    or a script file name as its first argument. The purpose of this command is
    to execute specified NppExec's script.
    Thus, if you use NPP_EXEC command, and its first argument (a script to be
    executed) depends on current file's extension, you can call different scripts
    for different file types from one starting script!
    Let's examine it in more detail.

    We are about to create a general NppExec's script which would allow us to
    call different scripts for different source files depending on their extension.
    In other words, we use the NPP_EXEC command to call required script, and the
    script name depends on current file's extension. The name of the script above,
    "run@.c", consists of two parts: the prefix "run@" and the extension ".c".
    As the file's extension can be got from Notepad++, we can write general form
    of this script's name: "run@$(EXT_PART)".
    It's not hard to understand that this script's name transforms to "run@.cpp"
    for .cpp source file, "run@.lua" for .lua source file and so on.
    So, let's create our general compile-or-run script which will be called each
    time you want compile or run ANY source file:

      // construct the script name to be called 
      SET Compiler = run@$(EXT_PART)
      // call the script
      NPP_EXEC "$(Compiler)"
     
    Save this script as "compile_or_run". Now this is your only starting script
    which will allow you to compile or run ANY source file. I.e. press F6, select
    the "compile_or_run" and press OK in order to compile or run ANY source file.
    However, don't forget that this script requires existing scripts for every
    source file you want to compile. Thus, "run@.cpp" must exist to compile a .cpp
    file, "run@.php" must exist to compile a .php file and so on.
    You can see several examples of such scripts below:

      // run@.c
      "C:\tools\tcc\tcc.exe" "$(FULL_CURRENT_PATH)" -run
     
      // run@.cpp
      SET g++ = C:\Dev-Cpp\bin\g++.exe
      SET obj = $(CURRENT_DIRECTORY)\$(NAME_PART)
      "$(g++)" -c "$(FULL_CURRENT_PATH)" -o "$(obj).o"
      "$(g++)" "$(obj).o" -o "$(obj).exe"
      NPP_RUN "$(obj).exe"
      UNSET obj
      UNSET g++
     
      // run@.awk
      "C:\tools\gawk\gawk.exe" -f "$(FULL_CURRENT_PATH)"
     
    All of these scripts will be started automatically from the "compile_or_run"
    script for .c, .cpp and .awk files. You can create more "run@..." scripts to
    support any source file extension you use.

    Now, let's return to our "compile_or_run" script. It uses the NPP_EXEC command
    which supports a script file name as its first argument. What does it mean?
    It means you can execute NppExec's script from a file.
    As you can see, current implementation of the "compile_or_run" script requires
    a lot of additional "run@..." scripts to exist together with other scripts
    which you may want to call explicitly. In the same time, you do not call the
    "run@..." scripts explicitly. So, the "run@..." scripts may be undesired in
    the NppExec's script combo-box (in the "Execute..." window).
    Thus, you may modify the "compile_or_run" script in order to call script files
    instead of internal scripts. For example:

      // compile_or_run
      SET Compiler = C:\tools\NppExec Scripts\run@$(EXT_PART).txt
      NPP_EXEC "$(Compiler)"
     
    Now you must create a directory "C:\tools\NppExec Scripts" which contains
    the following files: "run@.c.txt", "run@.cpp.txt", "run@.awk.txt" and so on.
    The text of these files must be exactly the same as in the scripts "run@.c",
    "run@.cpp" and "run@.awk" above.
    E.g. the file "C:\tools\NppExec Scripts\run@.awk.txt" must contain

      "C:\tools\gawk\gawk.exe" -f "$(FULL_CURRENT_PATH)"
     
    and so on for other file extensions (.c, .cpp, ...).
    To read more information about the NPP_EXEC command, open the NppExec's
    Console in Notepad++, and type:

      help npp_exec
     
    and press Enter.
    To get general NppExec's help information, type just

      help
     
    and press Enter.

    Well, seems it's time to finish the guide. I hope this guide was usefull for
    you, because otherwise it was waste of time for both of us: the reader (you)
    and the writer (me).
    If you like this guide, I hope it will inspire you to find your own usefull
    application of NppExec's functions, and maybe to share it with us.

     
    • Harry

      Harry - 2008-11-01

      That's surely an useful guide. Could you add it to the wiki too? That way it will always stay visible and can be adjusted/updated if something ever changes.

      Some thing I've wondered, I thought NppExec once had the ability to somewhat parse compiler output and allow you to go to a line with some error, was it like that and can it still be done?

       
      • DV

        DV - 2008-11-02

        Yes, NppExec can parse compiler's output.
        You can configure it from (main menu) Plugins -> NppExec -> Console Output Filters... -> HighLight.
        This window contains an example of parsing (highlighting) masks for GCC:

        Example 1: %ABSFILE%:%LINE%: warning:* => detects the warning lines generated by gcc
        Example 2: %ABSFILE%:%LINE%: error:*      => detects the error lines generated by gcc

        I.e. to enable detection (parsing) of GCC errors in NppExec, you must specify the mask of the compiler's error line ("%ABSFILE%:%LINE%: error:*") and, optionally, specify Red, Green and Blue components of the line to be highlighted and, also optionally, this line can be shown using Italic, Bold and/or Underlined font typeface. And, of course, corresponding check-box must be checked to enable this parsing mask.
        For example, if you want to see GCC's errors as Bold lines with Red colour and GCC's warnings as Italic lines with Blue colour, it will look somilar to the following:

        [v]  [%ABSFILE%:%LINE%: error:*          ]    0x80  0x00  0x00  [ ]  [v]  [ ]
        [v]  [%ABSFILE%:%LINE%: warning:*     ]    0x00  0x00  0x80  [v]  [ ]  [ ]

         
        • Harry

          Harry - 2008-11-03

          Thanks, I'm definitely going to try that some time. I especially missed it when working with Java, and this completely solved that :)

           
    • DV

      DV - 2008-12-04

      By the way, if you want you console program's output to be redirected in a text file, you can use something similar to the following:

      cmd /c C:\Tools\gawk\gawk.exe -f $(FULL_CURRENT_PATH) >$(SYS.TEMP)\out.txt

      Thus, if your current file in Notepad++ is some AWK program such as

      BEGIN {
          print "Hello, world!"
      }

      then the command above (which is started with "cmd /c") will create a file "out.txt" with the text "Hello, world!".

       
    • DV

      DV - 2008-12-04

      Just a reminder: (How to) Apply external tool to selected text
      https://sourceforge.net/forum/forum.php?thread_id=2109641&forum_id=672146

       
    • DV

      DV - 2008-12-04

      (How to) Using Visual Studio's compiler (cl.exe) with NppExec
      https://sourceforge.net/forum/message.php?msg_id=5746593

       
    • DV

      DV - 2008-12-08

      (How to) Compiling Java with Notepad++
      http://sourceforge.net/forum/forum.php?thread_id=2649646&forum_id=331754

      By the way, it's a good example of usage of the standard DOS functionality inherited and augmented by 'cmd.exe'. I mean all these "cmd /c", "&&" etc.

       
  • alzagor

    alzagor - 2010-03-01

    Weird question…

    Using your C++ example above, I modified it to open a DOS prompt (and keep it open after the .exe runs):

    SET g++ = D:\dev\c\MinGW\bin\g++.exe
    SET obj = $(CURRENT_DIRECTORY)\$(NAME_PART)
    "$(g++)" -o "$(obj)" "$(obj).cpp"
    NPP_RUN cmd /k "$(obj).exe"
    UNSET obj
    UNSET g++

    What I can't figure out ….
    How do I get CMD to open in the directory of the .exe?  CMD opens in the Notepad directory (C:\Program Files\Notepad++\)

    I sometimes have my code on a different drive, so I can't just use  "cd $(CURRENT_DIRECTORY)"
    Is there a generic solution that pops open CMD where ever the (CURRENT_DIRECTORY) is?

    (the problem is I sometimes output files from the created .exe… and those files get dumped into the Notepad++ directory)

     
  • DV

    DV - 2010-03-01

    As NppExec has its own internal implementation of such command as 'cd' (see section 1.3 of "NppExec.chm"), you can change both drive & directory using

    cd C:\Temp
    cd D:\Projects\My Project

    within NppExec's Console or NppExec's script.
    I.e.

    SET g++ = D:\dev\c\MinGW\bin\g++.exe
    SET obj = $(CURRENT_DIRECTORY)\$(NAME_PART)
    "$(g++)" -o "$(obj)" "$(obj).cpp"
    cd $(CURRENT_DIRECTORY)
    NPP_RUN cmd /k "$(obj).exe"
    UNSET obj
    UNSET g++

    or even

    SET g++ = D:\dev\c\MinGW\bin\g++.exe
    SET obj = $(NAME_PART)
    cd $(CURRENT_DIRECTORY)
    "$(g++)" -o "$(obj)" "$(obj).cpp"
    NPP_RUN cmd /k "$(obj).exe"
    UNSET obj
    UNSET g++

     
  • alzagor

    alzagor - 2010-03-02

    Wow - very cool!  That worked like a charm - thanks for the help  :)

     
  • alzagor

    alzagor - 2010-03-24

    Here's an odd one…
    Is it possible to only compile selected text using CURRENT_WORD ?

    I'm using this to test Ruby:

        SET ruby = D:\dev\ruby\bin\ruby.exe
        SET obj = $(NAME_PART)
        cd $(CURRENT_DIRECTORY)
        NPP_SAVE
        NPP_RUN cmd /k "$(ruby) $(obj).rb"
        UNSET obj
        UNSET ruby
    

    NPP_SAVE will save the whole current file, not take the CURRENT_WORD and dump it to a temp.rb file for testing.

     
  • DV

    DV - 2010-03-24

    SoHm.
    Let the "NppExec.txt" & "NppExec_Manual.chm" guide you.

    P.S.
    If you see just blank pages inside "NppExec_Manual.chm" then I insist you to write the following directly to Microsoft: why, WHY your STUPID system blocks the content of this file???

     
  • alzagor

    alzagor - 2010-03-26

    Thanks for the tip!   I did that before but didn't find anything.  Tried it again, dug a little deeper and got it to work.

    Here's how to only compile selected Ruby code (pops a dos window):

    SET ruby = D:\dev\ruby\bin\ruby.exe
    SET temp_file = $(SYS.TEMP)\ruby_sel.rb
    SEL_SAVETO $(temp_file) :a
    NPP_RUN cmd /k "$(ruby) $(temp_file)"
    UNSET ruby
    UNSET temp_file
    

    (I can't figure out what the ":a" flag is for though)

     
  • DV

    DV - 2010-03-27

    > (I can't figure out what the ":a" flag is for though)

    If you want the most detailed help about EVERY command of NppExec, follow this:
    (Notepad++ main menu) Plugins -> NppExec -> Help/Manual -> topic "3.1. Getting help".

    P.S.
    If you see just blank pages there (inside "NppExec_Manual.chm") then I insist you to write the following directly to Microsoft: why, WHY your STUPID system blocks the content of this file???

     

Log in to post a comment.