Author Topic: Run LISP code from NotePad++  (Read 624 times)

0 Members and 1 Guest are viewing this topic.

Grrr1337

  • Swamp Rat
  • Posts: 735
Run LISP code from NotePad++
« on: September 09, 2020, 05:23:20 PM »
Hey guys!  :idea:
Just wanted to share this project for the ones of you who are used (like me) to write their code in NP++
Code - Auto/Visual Lisp: [Select]
  1. ; This routine runs the code in the active editor of NotePad++ from AutoCAD:
  2. (defun C:n++ nil (C:RunFromNotePadPP)) ; Quick Run
  3. (defun C:RunFromNotePadPP ( / scr *error* err np++ npeditor npSS npMS r des lsp fn )
  4.   ; NOTE: Requires ActiveX plugin(by David Gausmann) installed on the NP++
  5.   ; https://sourceforge.net/projects/nppactivexplugin/
  6.   ;| Sample code in the active editor would look like (copy any of the samples in a new editor window that should remain active):
  7.  
  8.   ; Sample #1
  9.   (defun test ( / q )
  10.     (if (setq q (= "Yes" (progn (initget "Yes No") (cond ((getkword "\nSay hello ? [Yes/No] <Yes>: ")) ("Yes")))))
  11.       (alert "Hello!")
  12.     )
  13.     '(I just said hello)
  14.   )
  15.   (test); <<-- Obviously if you comment the call, it will just load it
  16.  
  17.   ; Sample #2
  18.   (defun test ( / q )
  19.     (if (setq q (= "Yes" (progn (initget "Yes No") (cond ((getkword "\nTHIS IS SAMPLE #2 !! [Yes/No] <Yes>: ")) ("Yes")))))
  20.       (alert "Hello!")
  21.     )
  22.     'sample#2
  23.   )
  24.   (test)
  25.  
  26.   ; Sample #3 - call (C:n++) or (C:RunFromNotePadPP) from VLIDE's console
  27.   ( (lambda (f) (f 10 nil))
  28.     (lambda (n c)
  29.       (if (> n 0)
  30.         (f (1- n) (cons (* n n) c))
  31.         c
  32.       )
  33.     )  
  34.   )
  35.  
  36.   ; Sample #4 (checking if subfuns are loading aswell)
  37.   (defun C:test ( / p )
  38.     (and
  39.       (setq p (getpoint "\nPick a point: "))
  40.       (foreach v (vL 10)
  41.         (MkPt (mapcar '+ p v))
  42.       ); foreach
  43.     )
  44.     (princ)
  45.   )
  46.   (defun vL (n) (list '(0 0 0) (list n 0 0) (list 0 n 0) (list (- n) 0 0) (list 0 (- n) 0)))
  47.   (defun MkPt (p) (entmake (list '(0 . "POINT") (cons 10 p))))
  48.   (C:test)
  49.  
  50.   ; Sample #5
  51.   '(any type of data can be loaded)
  52.   "Wherever it is string, number or symbol, function or an evaluation."
  53.   123
  54.   'abc
  55.   lambda
  56.   (mapcar '* '(1 2 3) '(4 5 6))
  57.   |;
  58.  
  59.   (setq scr (getvar 'secureload))
  60.   (defun *error* (m)
  61.     (foreach x (reverse (list np++ npeditor npSS npMS))
  62.       (vl-catch-all-apply (function vlax-release-object) (list x))
  63.     )
  64.     (gc) (gc)
  65.     (and scr (setvar 'secureload scr))
  66.     (and (eq 'FILE (type des)) (close des))
  67.     (and (eq 'STR (type lsp)) (findfile lsp) (vl-file-delete lsp))
  68.     (and msg (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*") (princ (strcat "\nError: " msg)))) (princ)
  69.   ); defun *error*
  70.  
  71.  
  72.  
  73.   (setq err
  74.     (vl-catch-all-apply
  75.       (function
  76.         (lambda nil
  77.           (setq np++ (vlax-get-or-create-object "NotepadPlusPlus.Application"))
  78.           (setq npeditor (vlax-get np++ 'ActiveEditor))
  79.           (vlax-invoke-method npeditor 'selectAll)
  80.           (setq npSS (vlax-get npeditor 'selections))
  81.           (setq npMS (vlax-get npSS 'mainSelection))
  82.           (setq r (vlax-get-property npMS 'text))
  83.           (vlax-invoke npSS 'setRange 0 0 0 0)
  84.         ); lambda
  85.       ); function
  86.     ); vl-catch-all-apply
  87.   ); setq err
  88.  
  89.   (and
  90.     r (not (vl-catch-all-error-p err))
  91.     (setq lsp (vl-filename-mktemp nil nil ".lsp"))
  92.     (setq des (open lsp "w"))
  93.     (princ r des)
  94.     (not (setq des (close des)))
  95.     (progn
  96.       (setq r (vl-catch-all-apply (function (lambda nil (setvar 'secureload 0) (load lsp)))))
  97.     )
  98.   ); and
  99.  
  100.   (*error* nil)(princ) r
  101. ); defun

The procedure is the following:
Just write whatever in the active editor of NP++, and then switch to ACAD and call the 'N++' command to execute it.
Or call (C:N++) in VLIDE to check the return of the thing you write.
NOTE: No loading, saving or copy-pasting required - just make changes and call 'N++'

Perhaps if this approach is chained with a certain type of reactor it would be even more dev-friendly.  :thinking:
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)

VovKa

  • Swamp Rat
  • Posts: 1272
  • Ukraine
Re: Run LISP code from NotePad++
« Reply #1 on: September 09, 2020, 07:15:20 PM »
why don't you just use (eval (read r)) instead of writing to a file?

Grrr1337

  • Swamp Rat
  • Posts: 735
Re: Run LISP code from NotePad++
« Reply #2 on: September 10, 2020, 05:04:35 AM »
why don't you just use (eval (read r)) instead of writing to a file?

I initially did that, but noticed that only the first function being evaluated, and not the rest.
I.E. for Sample #4 it won't load the helper functions  (defun vL ..) and  (defun MkPt ..)
Code - Auto/Visual Lisp: [Select]
  1. _$ (eval (read "\r\n\r\n\r\n(defun C:test ( / p )\r\n  (and \r\n    (setq p (getpoint \"\\nPick a point: \"))\r\n    (foreach v (vL 10)\r\n      (MkPt (mapcar '+ p v))\r\n    ); foreach \r\n  )\r\n  (princ)\r\n)\r\n(defun vL (n) (list '(0 0 0) (list n 0 0) (list 0 n 0) (list (- n) 0 0) (list 0 (- n) 0)))\r\n(defun MkPt (p) (entmake (list '(0 . \"POINT\") (cons 10 p))))\r\n(C:test)" ))
  2. C:TEST
So obviously after trying to call the loaded routine I will get no function definition error.

Another example of the problem is with Sample #5:
Code - Auto/Visual Lisp: [Select]
  1. _$ (eval (read "\r\n\r\n\r\n  '(any type of data can be loaded)\r\n  \"Wherever it is string, number or symbol, function or an evaluation.\"\r\n  123\r\n  'abc\r\n  lambda \r\n  (mapcar '* '(1 2 3) '(4 5 6))"))
  2. (ANY TYPE OF DATA CAN BE LOADED)

(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)

VovKa

  • Swamp Rat
  • Posts: 1272
  • Ukraine
Re: Run LISP code from NotePad++
« Reply #3 on: September 10, 2020, 08:16:15 AM »
Code: [Select]
(eval (read (strcat "(progn\n" r "\n)")))

Grrr1337

  • Swamp Rat
  • Posts: 735
Re: Run LISP code from NotePad++
« Reply #4 on: September 10, 2020, 12:41:41 PM »
Thanks Vova, I've forgot about the possibility of utilising the "really long progn",
although I used list instead, because progn would return the last evaluation, while with list would be possible to check everything thats loaded.

So the modification of my routine is this:

Code - Auto/Visual Lisp: [Select]
  1. ; This routine runs the code in the active editor of NotePad++ from AutoCAD:
  2. (defun C:n++ nil (C:RunFromNotePadPP)) ; Quick Run
  3. (defun C:RunFromNotePadPP ( / scr *error* err np++ npeditor npSS npMS r )
  4.   ; NOTE: Requires ActiveX plugin(by David Gausmann) installed on the NP++
  5.   ; https://sourceforge.net/projects/nppactivexplugin/
  6.  
  7.   (defun *error* (m)
  8.     (foreach x (reverse (list np++ npeditor npSS npMS))
  9.       (vl-catch-all-apply (function vlax-release-object) (list x))
  10.     )
  11.     (gc) (gc)
  12.     (and msg (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*") (princ (strcat "\nError: " msg)))) (princ)
  13.   ); defun *error*
  14.  
  15.   (setq err
  16.     (vl-catch-all-apply
  17.       (function
  18.         (lambda nil ; THIS WORKS - IT GETS THE ACTIVE DOCUMENT CODE IN NOTEPAD !!!
  19.           (setq np++ (vlax-get-or-create-object "NotepadPlusPlus.Application"))
  20.           (setq npeditor (vlax-get np++ 'ActiveEditor))
  21.           (vlax-invoke-method npeditor 'selectAll)
  22.           (setq npSS (vlax-get npeditor 'selections))
  23.           (setq npMS (vlax-get npSS 'mainSelection))
  24.           (setq r (vlax-get-property npMS 'text))
  25.           (vlax-invoke npSS 'setRange 0 0 0 0)
  26.         ); lambda
  27.       ); function
  28.     ); vl-catch-all-apply
  29.   ); setq err
  30.  
  31.   (*error* nil)(princ)
  32.   (if (and r (not (vl-catch-all-error-p err)))
  33.     (eval (read (strcat "(list\n" r "\n)")))
  34.   )
  35. ); defun

And here are some tests performed on a few of the samples inside VLIDE's console:
Code - Auto/Visual Lisp: [Select]
  1. _$ (C:N++)
  2. (C:TEST VL MKPT)
  3. _$ (C:N++)
  4. ((1 4 9 16 25 36 49 64 81 100))
  5. _$ (C:N++)
  6. ((ANY TYPE OF DATA CAN BE LOADED) "Wherever it is string, number or symbol, function or an evaluation." 123 ABC #<SUBR @00000013d01ed5c0 LAMBDA> (4 10 18))
  7. _$ (foreach x (C:N++) (print x))
  8.  
  9. (ANY TYPE OF DATA CAN BE LOADED)
  10. "Wherever it is string, number or symbol, function or an evaluation."
  11. 123
  12. ABC
  13. #<SUBR @00000013d01ed5c0 LAMBDA>
  14. (4 10 18) (4 10 18)
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)

BIGAL

  • Swamp Rat
  • Posts: 516
  • 30 + years of using Autocad
Re: Run LISP code from NotePad++
« Reply #5 on: September 10, 2020, 09:48:18 PM »
Tried it out and works great will probably use more often.
A man who never made a mistake never made anything

Grrr1337

  • Swamp Rat
  • Posts: 735
Re: Run LISP code from NotePad++
« Reply #6 on: September 11, 2020, 05:50:47 AM »
Tried it out and works great will probably use more often.

Thanks for confirming, BIGAL ! :)
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)

BIGAL

  • Swamp Rat
  • Posts: 516
  • 30 + years of using Autocad
Re: Run LISP code from NotePad++
« Reply #7 on: September 11, 2020, 07:50:52 PM »
Read a couple of times after downloading the vlx extension

Requires ActiveX plugin(by David Gausmann) installed in  Notepad++ 1st. There is a c:\program files\Notepad\plugins directory add the vlx there. Then run Plugins from Notepad++
A man who never made a mistake never made anything

Rustabout

  • Newt
  • Posts: 51
Re: Run LISP code from NotePad++
« Reply #8 on: September 15, 2020, 09:47:03 PM »
Pretty amazing stuff!

Do you suppose it will work in the 'cad clones' as well?

Also (slightly unrelated), but does N++ have a DCL plugin as well?

MatGrebe

  • Mosquito
  • Posts: 7
Re: Run LISP code from NotePad++
« Reply #9 on: September 16, 2020, 03:07:24 AM »
In BricsCAD it works !
Mathias

BIGAL

  • Swamp Rat
  • Posts: 516
  • 30 + years of using Autocad
Re: Run LISP code from NotePad++
« Reply #10 on: September 16, 2020, 08:32:06 PM »
If this is supported then it should work

(setq np++ (vlax-get-or-create-object "NotepadPlusPlus.Application"))
A man who never made a mistake never made anything

VovKa

  • Swamp Rat
  • Posts: 1272
  • Ukraine
Re: Run LISP code from NotePad++
« Reply #11 on: September 17, 2020, 05:56:46 AM »
but does N++ have a DCL plugin as well?
dcl is nothing special
it can be treated the same way VLIDE does it:
it creates a temporary file "$vld$.dcl" in Acad's folder
adds "dcl_settings : default_dcl_settings { audit_level = 1; }" at the beginning
then calls
Code: [Select]
((lambda (/ id)
   (setq id (LOAD_DIALOG "$vld$.dcl"))
   (cond ((>= id 0)
  (if (NEW_DIALOG (GuessDialogName r) id "(done_dialog)")
    (START_DIALOG)
  )
  (UNLOAD_DIALOG id)
)
   )
 )
)
and does not even deletes this junk file afterwards :)