Configura scite per lavorare con newLisp

9 08 2009

google_translate.gif
Translate To English!

newLisp è un linguaggio cross-platform, e trovare un ottimo editor, flessibile e relativamente semplice da usare, che sia pure esso stesso cross-platform non è stata una cosa facile. Alcuni editor sono fantastici ma non sono cross-platform, altri sono un pò “duri” da gestire (comandi solo da tastiera, linguaggi di scripting per macro e plugin proprietari, etc…), altri ancora sono fantastici ma avete bisogno di MOLTO tempo per imparare a gestirli a dovere. Dopo varie ricerche ho scelto Scite, un ottimo cross platform editor (anche se c’è da fare un pò di fine-tuning per quanto riguarda le configurazioni interne).
Sono stato ancora più felice quando ho scoperto che Kazimir, nel suo blog, aveva pubblicato un file per fare syntax highlight e quant’altro in Scite! L’ho quindi subito scaricato e mi sono messo al lavoro per personalizzare il mio Scite editor, creando il mio ambiente di lavoro “perfetto” (il file “properties” originale di Kazimir lo potete trovate a questo indirizzo: http://kazimirmajorinc.blogspot.com/2008/06/lispproperties-for-scite.html).
Studiando un pò mi sono poi accorto che Scite permette di scrivere delle macro in LUA (non in newLisp purtroppo :-)  ). Questo permette di raggiungere ottimi livelli di personalizzazione dell’editor. In questo articolo pubblicherò il mio file properties di Scite. Ogni volta che apporterò modifiche/aggiornamenti su tale file, o creerò scripts/plugins, li pubblicherò qui, con la categoria:  Scite Editor. Partendo quindi dal file properties generato da Kazimir, l’ho modificato ed esteso un pò.

NOTA: non fermatevi a vedere solo il codice sorgente! Alla fine del listato, ho scritto dei commenti in merito alle varie proprietà, così che voi stessi potrete voi stessi personalizzare il file per le vostre esigenze!
NOTA 2: ho creato il file su Scite per Linux, ed ho notato delle piccole differenze su quello Windows (per esempio, il background non è nero). Io non ho però nessun PC con Windows, sto quindi lavorando per fare dei tests su tale sistema operativo, facendo poi le modifiche necessarie (che pubblicherò puntualmente!).

CODICE SORGENTE DEL FILE “LISP.PROPERTIES”

# Define SciTE settings for Newlisp files.
view.whitespace=0
whitespace.fore=#333333
split.vertical=0
strip.trailing.spaces=1
strip.trailing.tabs=1
reload.preserves.undo=1

# Indentation
use.tabs=1
tab.size=4
tab.indent=1
backspace.unindents=1
indent.opening=1
indent.closing=1
indent.size=4
indent.auto=1
indent.automatic=1
view.indentation.guides = 1
view.indentation.examine = 3
highlight.indentation.guides = 1

# Editor starting position and size.
position.left=10
position.top=10
position.width=600
position.height=400

# Right edge
edge.column=80
edge.mode=1
edge.colour=#AAAAAA

# Sizes and visibility in edit pane
line.margin.visible=1
line.margin.width=4
margin.width=14
fold.margin.width=14
fold.margin.colour=#007F00
fold.margin.highlight.colour=#007F00

# caret
caret.fore=#FF0000
caret.width=3
caret.period=500

selection.back=#FF0000

file.patterns.lisp=*.lsp;*.lisp
filter.lisp=LISP (lsp lisp)|$(file.patterns.lisp)|

lexer.$(file.patterns.lisp)=lisp

# Lisp build in functions
keywords.$(file.patterns.lisp)= $ \
$ ! != $ $0 $1 $10 $11 $12 $13 $14 $15 $2 $3 $4 $5 $6 $7 $8 $9 \
$args $idx $it $main-args % & * + - / : < << <= = > >= >> ? @ \
class MAIN NaN? Tree abort abs acos acosh add address amb and \
append append-file apply args array array-list array? asin asinh \
assoc atan atan2 atanh atom? base64-dec base64-enc bayes-query \
bayes-train begin beta betai bind binomial bits callback case \
catch ceil change-dir char chop clean close command-event cond \
cons constant context context? copy copy-file cos cosh count \
cpymem crc32 crit-chi2 crit-z current-line curry date date-value \
debug dec def-new default define define-macro delete delete-file \
delete-url destroy det device difference directory directory? div \
do-until do-while doargs dolist dostring dotimes dotree dump dup \
empty? encrypt ends-with env erf error-event error-number error-text \
eval eval-string exec exists exit exp expand explode factor fft \
file-info file? filter find find-all first flat float float? floor \
flt for for-all format fv gammai gammaln gcd get-char get-float \
get-int get-long get-string get-url global global? if if-not ifft \
import inc index int integer integer? intersect invert irr join \
lambda? last legal? length let letex letn list list? load local \
log lookup lower-case macro? main-args make-dir map mat match max \
member min mod mul multiply name net-accept net-close net-connect \
net-error net-eval net-interface net-listen net-local net-lookup \
net-peek net-peer net-receive net-receive-from net-receive-udp \
net-select net-send net-send-to net-send-udp net-service net-sessions \
new nil nil? normal not now nper npv nth null? number? open or \
ostype pack parse pipe pmt pop pop-assoc post-url pow pretty-print \
primitive? print println prob-chi2 prob-z process prompt-event \
protected? push put-url pv quote quote? rand random randomize \
read-buffer read-char read-expr read-file read-key read-line \
real-path ref ref-all regex regex-comp remove-dir rename-file \
replace reset rest reverse rotate round save search seed seek \
select semaphore sequence series set set-locale set-ref set-ref-all \
setf setq sgn share signal silent sin sinh sleep slice sort source \
spawn sqrt starts-with string string? sub swap sym symbol? symbols \
sync sys-error sys-info tan tanh throw throw-error time time-of-day \
timer title-case trace trace-highlight transpose trim true true? \
unify unique unless unpack until upper-case uuid when while \
write-buffer write-char write-file write-line xml-error xml-parse \
xml-type-tags zero? | ~ \

word.chars.lisp=$(chars.alpha)$(chars.numeric)_-<>.#+@$%^&=*!?`§
word.characters.$(file.patterns.lisp)=$(word.chars.lisp)

comment.block.lisp=;
comment.box.start.lisp=;
comment.box.middle.lisp=;
comment.box.end.lisp=;
comment.stream.start.lisp=;111
comment.stream.end.lisp=;222

# White space
style.lisp.0=fore:#00FF00,back:#000000,size:10

# Line Comment
style.lisp.1=fore:#FFFF66,back:#000000,size:10

# Number
style.lisp.2=fore:#7F7FFF,back:#000000,size:10

# Keyword
style.lisp.3=fore:#FFCF00,back:#000000,size:10

# Unknown
style.lisp.4=back:#FFFFFF

# Quoted identifier
style.lisp.5=fore:#00FF00,back:#333344

# String
style.lisp.6=fore:#7FFFFF,back:#000000

# End of line where string is not closed
style.lisp.7=back:#FFFFFF,back:#000000

# Unknown
style.lisp.8=back:#FFFFFF,back:#000000

# Identifiers
style.lisp.9=fore:#00FF00,back:#000000

# Operators
style.lisp.10=fore:#FF7FFF,back:#000000

# -- syntax
style.lisp.11=back:#FFFFFF

# Undefined or unknown styles
style.lisp.12=back:#00FF00
style.lisp.13=back:#FFFF00
style.lisp.14=back:#FFFF00
style.lisp.15=back:#FFFF00
style.lisp.16=back:#FFFF00
style.lisp.17=back:#FFFF00
style.lisp.18=back:#FFFF00
style.lisp.19=back:#FFFF00
style.lisp.20=back:#FFFF00
style.lisp.21=back:#FFFF00
style.lisp.22=back:#FFFF00
style.lisp.23=back:#FFFF00
style.lisp.24=back:#FFFF00
style.lisp.25=back:#FFFF00
style.lisp.26=back:#FFFF00
style.lisp.27=back:#FFFF00
style.lisp.28=back:#FFFF00
style.lisp.29=back:#FFFF00
style.lisp.30=back:#FFFF00
style.lisp.31=back:#FFFF00

# Default selected text COLORS.
selection.back=#FFFFFF
selection.alpha=80

# Monospace per default
font.base=font:Courier,size:10
font.small=font:Courier,size:10
font.comment=font:Courier,size:10
font.code.comment.box=$(font.comment)
font.code.comment.line=$(font.comment)
font.code.comment.doc=$(font.comment)
font.text=font:times,size:10
font.text.comment=font:Courier,size:10
font.embedded.base=font:Courier,size:10
font.embedded.comment=font:Courier,size:10
font.monospace=font:Courier,size:10
font.vbs=font:Courier,size:10

# Code completion
autocompleteword.automatic=1
autocomplete.choose.single=0
lexer.$(file.patterns.flash)=lisp
autocomplete.flash.ignorecase=1

# Default
style.lisp.32=fore:#FF0000,back:#000000,size:10

# Line number
style.lisp.33=back:#00FF00,fore:#000000,size:10

# Brace highlight
style.lisp.34=back:#007f00,fore:#FFFF00,size:10

# Brace incomplete highlight
style.lisp.35=back:#7f0000,fore:#FFFF00,size:10

# Control characters
style.lisp.36=back:#000000;fore:#FF00FF,size:10

# Indentation guides
style.lisp.37=fore:#A00000,back:#000000,size:10

# Braces are only matched in operator style
# braces.lisp.style=10

# TOOLS
command.go.$(file.patterns.lisp)=cmd /K "newlisp -c -s 400000 $(FilePath)"
command.go.subsystem.$(file.patterns.lisp)=2

command.name.0.$(file.patterns.lisp)=Go (Output Box)
command.0.$(file.patterns.lisp)=cmd /K "newlisp -c $(FilePath)"
command.subsystem.0.$(file.patterns.lisp)=0

command.name.1.$(file.patterns.lisp)=Newlisp REPL (Command Window)
command.1.$(file.patterns.lisp)=cmd /K "newlisp"
command.subsystem.1.$(file.patterns.lisp)=2

command.name.2.$(file.patterns.lisp)=Newlisp REPL (Output)
command.2.$(file.patterns.lisp)=cmd /K "newlisp"
command.subsystem.2.$(file.patterns.lisp)=0

command.help.$(file.patterns.lisp)="C:/Program Files (x86)/newlisp/manual_frame.html"
command.help.subsystem.$(file.patterns.lisp)=2

Cosa da, e soprattutto: come si usa?!

  1. Scaricate Scite dalla sua home page (trovate il link anche nell’apposita sezione di questo blog).
  2. Aprite il file lisp.properties. Nota per gli utenti Linux: il file non può essere modificato come utente normale, quindi entrate in modalità root con il comando “sudo”, oppure con il comando “su”.
  3. Fate un backup del “vecchio” file lisp.properties (quello che andremo a sostituire).
  4. Sostituite il file appena aperto con quello che ho pubblicato.
  5. Salvate il tutto. Chiudete Scite e riaprite. Poi…
  6. … poi aprite un file newLisp (estensione “.lsp”).

Ecco come si presenta Scite con il file newLisp aperto: newlisp final Questo file “properties” permette di avere, in Scite, le seguenti funzionalità:

  1. Highlight della sintassi.
  2. Highlight delle parentesi tonde.
  3. Highlight dell’indentazione.
  4. Code completion (CARLO-ENTER).
  5. Eliminazione (pulizia) degli spazi e TABE in eccesso sulla riga (quelli oltre l’ultimo carattere scritto).
  6. Indentazione automatica.
  7. Possibilità di personalizzare la posizione iniziale e la dimensione dell’editor allo start-up.
  8. Posizionamento del “right edge” (linea sottile che mostra il bordo destro dell’editor – default al carattere 80). Possibilità di personalizzare il suo colore.
  9. Possibilità di personalizzare i colori del cursore e la sua frequenza di lampeggio.
  10. Per default, viene impostato il carattere di tipo MONOSPACE.

Rispetto alle impostazioni di Kazimir, ho modificato alcune combinazioni di colori e fonts. Sono scelte molto personali, quindi fate la vostra!

Una breve spiegazione sul file

Vorrei mettere in evidenza alcune parti del file, così che voi potrete personalizzarlo a vostro piacere.

view.whitespace=0
Serve per poter mostrare dei piccoli puntini al posto degli spazi (potete così mettere “in evidenza” gli spazi).

strip.trailing.spaces=1
strip.trailing.tabs=1
Configura Scite per eliminare SPAZI e TABS alla fine di ogni riga. Per esempio: <Questa è una riga di esempio                    > Gli spazi alla fine della riga verranno eliminati.

use.tabs=1
tab.size=4
tab.indent=1
Questi parametri indicano che il TAB può indentare il codice. Ogni TAB include 4 caratteri di indentazione.

backspace.unindents=1
Il tasto BACKSPACE permetterà di eliminare un livello di indentazione del codice.

indent.size=4
indent.auto=1
indent.automatic=1
Dettagli sull’indentazione stessa. E’ automatica (quindi ad ogni pressione del tasto ENTER il cursore si posiziona al livello di indentazione corretto rispetto al precedente, e non all’inizio della riga).

view.indentation.guides = 1
view.indentation.examine = 3
highlight.indentation.guides = 1
Mostrano le linee guida di indentazione.

# Editor starting position and size.
position.left=100
position.top=30
position.width=600
position.height=400
Autoesplicativo!  Posizione e dimensioni iniziali dell’editor. Suggerimento: questo codice, se volete che venga eseguito ogni volta che si apre l’editor (e non solo per files newLisp), mettetelo in SciTEGlobal.properties

# Right edge
edge.column=100
edge.mode=1
edge.colour=#AAAAAA
Limite destro di scrittura: posizione (colonna 100), attivato (edge.mode=1) e con colore grigio.

# Sizes and visibility in edit pane
line.margin.visible=1
line.margin.width=4
margin.width=14
fold.margin.width=14
fold.margin.colour=#007F00
fold.margin.highlight.colour=#007F00
Caratteristiche del bordo a sinistra dell’editor, cioè la parte in cui compare il numero di riga, i bookmarks, etc…

caret.fore=#FF0000
caret.width=3
caret.period=500

Caratteristiche del cursore: in particolare caret.width rappresenta lo “spessore” del cursore in modo insert (cioè quando ha la forma di una linea verticale, come una pipe).

# Default selected text COLORS.
selection.back=#FFFFFF
selection.alpha=80
Quando selezionate del testo, usando per esempio il mouse, tale selezione compare come se fosse “evidenziata”. Questi sono i parametri di tale evidenziazione. Nel mio codice ho posto un colore di evidenziazione bianco (#FFFFFF) ma con un coefficiente di trasparenza di 80 (0-255).

# Monospace per default
L’intero blocco è necessario per indicare a Scite di usare in ogni circostanza dei fonts MONOSPACE (personalmente detesto scrivere programmi con fonts proporzionali!).

# Code completion
autocompleteword.automatic=1
autocomplete.choose.single=0
lexer.$(file.patterns.flash)=lisp
autocomplete.flash.ignorecase=1
Parametri necessari per il code completion. L’opzione autocomplete.choose.single=0 indica al parser lessicale di non includere solo una opzione in output (come suggerimento), ma tutte le parole chiave che rispettano la parola scritta.

Anche stavolta siamo giunti al termine, alla prossima!





Scrivere funzioni newLisp auto-commentate

11 07 2009

google_translate.gif Translate To English!

Introduzione

Una cosa che mi piacque molto quando studiai per la prima volta Rebol (un bellissimo linguaggio di programmazione funzionale, creato da Carl Sassenrath), è che si potevano inserire dei commenti all’interno delle funzioni stesse. Cercherò di essere un pò più chiaro. Normalmente, se scrivo un programma in Java (ma anche in C, Pascal, Basic, etc…) scrivo i commenti alle funzioni in un modo simile al seguente:

/* Questo è il commento alla mia  bellissima funzione */
function miaFunzione() {
   faccioQualcosa();
}

Il commento (quello in mezzo ai simboli /*  */ ), anche se posto sopra alla funzione stessa, è però staccato, indipendente da essa, sotto ogni punto di vista. Solo utilizzando programmi esterni (come javadoc) si può allora generare della documentazione che “colleghi” il commento alla funzione. Inoltre, se spostassi la funzione, o la mettessi in un altro programma, potrei anche dimenticare di copiare il suo commento. Nei linguaggi funzionali come newLisp e Rebol, possiamo però sfruttare la loro omoiconicità per inserire il commento all’interno della funzione stessa. Questo ci porterà notevoli vantaggi:

  1. Se copio / sposto la funzione, il commento verrà copiato con essa, sempre.
  2. Molti linguaggi di scripting (compreso newLisp) hanno una comoda console per impartire i comandi. Questo significa che, si possono realizzare dei comandi ad-hoc, per leggere tali commenti, direttamente dalla funzione stessa, e senza ricorrere a programmi esterni (simili a javadoc).
  3. Il commento (e la documentazione in genere), non essendo necessario estrarlo con tools esterni, sarà sempre aggiornato (non rischio di avere una funzione X ma con un commento estratto Y – più vecchio della funzione stessa, solo perchè non ho rilanciato il comando di aggiornamento della documentazione).
Passiamo alla pratica

Ora che ho chiarito (spero!) un pò meglio la mia idea, cerchiamo di capire come metterlo in pratica usando il nostro newLisp. Prima di tutto scriviamo una funzione molto semplice:

(define (somma-valori argValore1 argValore2)
   (println (+ argValore1 argValore2) )
)
>> (somma-valori 10 20)
30

Bene, ora che ho la funzione, inseriamo un breve commento per spiegare il suo funzionamento. Lo possiamo fare in diversi modi, in base al numero di informazioni (e al tipo) da mettere. Il sistema più semplice è inserire una stringa che contenga il commento (ma newLisp ci permetterà di fare ben altro!):

(define (somma-valori argValore1 argValore2)
   "Questa funzione addiziona due numeri interi."
   (println (+ argValore1 argValore2) )
)

La possibilità unica nel suo genere che hanno i linguaggi omoiconici è che il codice (il programma vero e proprio) e i dati sono in realtà la stessa cosa, quindi newLisp non si “scandalizza” se, nel bel mezzo di un programma, inseriamo una stringa, senza chiamare funzioni, senza assegnazioni! Ma ora arriva la parte più interessante: proprio perchè in newLisp i dati sono codice, ed il codice sono dati, possiamo manipolare la nostra funzione come una lista qualunque, quindi:

>> (nth 1 somma-valori)
"Questa funzione addiziona due numeri interi."

Meraviglioso! Abbiamo potuto estrarre il commento dalla funzione! Ora guardate qui… create nel vostro ambiente newLisp (dalla console) questa funzione:

(define (helpme argFunction)
   (nth 1 argFunction)
)

Ora provate a digitare:

>> (helpme somma-valori)
"Questa funzione addiziona due numeri interi."

Fantastico! Basta quindi stabilire uno standard ed avremo, gratis (  :-)  ) , un comodo sistema di help online! Ma allora, perchè fermarci qui? Proviamo in questo modo:

(define (somma-valori argValore1 argValore2)
   (
      (comment "Questa funzione addiziona due numeri interi.")
      (version 1.1)
      (last-update "2009-07-01")
   )
   (println (+ argValore1 argValore2) )
)

Il nostro semplice commento, scritto sottoforma di stringa, ora è diventato una lista, contenente dei “tag” (comment / version / last-update) rileggibili dalla nostra funzione di help:

(define (helpme argFunction)
   ( println "DESCRIPTION: " (lookup 'comment (nth 1 argFunction)) )
   ( println "VERSION    : " (lookup 'version (nth 1 argFunction)) )
   ( println "LAST-UPDATE: " (lookup 'last-update (nth 1 argFunction)) "\n" )
)

>> (helpme somma-valori)
DESCRIPTION: Questa funzione addiziona due numeri interi.
VERSION    : 1.1
LAST-UPDATE: 2009-07-01

I vantaggi di un metodo simile sono evidenti: se aggiungessimo anche una funzione per indicizzare le funzioni scritte (quindi potendo anche cercarle scrivendo solo una parte del loro nome), allora avremo un ambiente di sviluppo e test di prim’ordine!

Anche stavolta siamo quasi alla fine. Spero che l’articolo possa fornirvi spunti utili al vostro lavoro e divertimento!

A presto!





CrunchBang linux, *newLisp*, zenity, lighttpd, dmenu, Opera & Netbooks!

25 06 2009

google_translate.gif Translate To English!

Eccomi di nuovo qui con un articolo in parte off-topic (ma non troppo!). Questa volta però ho deciso di confondervi le idee, immettendo un titolo a questo articolo decisamente strano.
Insomma, di cosa parliamo stavolta? Si parlerà della moda del momento: i netbooks! Si tratta di moda o vera necessità? Dovè la verità? Il tempo ce lo dirà (oltre che programmatore sono diventato anche poeta! Guarda che rima che ho fatto!).

Al di là delle questioni “filosofiche”, è un dato di fatto che i netbooks stanno riscuotendo un enorme successo. Purtroppo però sembra che, come troppo spesso accade, una bella idea (vera innovazione o evoluzione?) venga un poco rovinata da ciò che la circonda. Piccoli gioielli come questi si meriterebbero anche dei sistemi operativi adeguati, ma nonostante sia passato un pò di tempo, siamo ancora in alto mare (ok, ok, ci sono molte distribuzioni linux, ma a mio parere siamo ancora lontani da quello che dovrebbe essere il vero sistema operativo per sfruttare appieno questi piccoli computers). Al di là poi della “potenza” del netbook stesso, anche le interfacce dovrebbero cambiare radicalmente. Certo che diverse distribuzioni linux hanno fatto molti passi in avanti, però ho l’impressione che l’obiettivo finale (a lungo termine) non verrà centrato (la direzione in cui si sta andando sembra giusta però, a mio parere, manca ancora qualcosa… forse con Moblin 2 – creato come O.S. più simile a quello di un cellulare che ad un O.S. tradizionale – cambierà qualcosa, ma ci sono ancora troppe applicazioni “standard”).

Va bene, non sono però qui a scrivere per parlare della validità di questo programma o di quell’altro sistema operativo, ma vorrei invece darvi un suggerimento, da veri smanettoni, per creare una distribuzione linux veramente adatta alle vostre esigenze.
Ho da poco provato la distribuzione linux CrunchBang Linux e, anche se un pò “scarna” per un profano, credo sia un autentico gioiello se messa nelle mani di uno smanettone. Si configura con pochi files di testo (xml), ha dei tools semplici ma efficaci, è molto leggera (sul mio netbook Acer Aspire One A110 occupa meno di 100Mb di RAM quando è in funzione), ed è VELOCE (deriva da Ubuntu 8.10).

newLisp funziona magnificamente.

Se vi serve un web server vi consiglio lighttpd. E’ veloce (parte in un baleno), si configura con un file di testo, supporta le CGI (pure quelle fatte in newLisp), ed occupa pochissima memoria.

Se volete realizzare degli script di configurazione/personalizzazione della distro, potete usare zenity e dmenu . Il primo è un programma che, lanciato a linea comando, permette di generare delle forms grafiche (vedi il mio precedente articolo: http://newlisp.wordpress.com/2009/05/01/usare-newlisp-nella-shell-di-linux/ ). Mentre il secondo è un meraviglioso programma in grado di generare un menu a partire da un input generico, prendere la selezione dell’utente (item scelto tra quelli proposti nel menu) e ritornarlo alla linea comando. Può gestire ricerche tra le voci proposte, ed lavora agevolmente con migliaia di items (esempio: digitate ls -l | dmenu ed avrete già pronto un menu di selezione di un file). Questi due software sono favolosi se accoppiati a newLisp!

Riguardo Opera, ne ho già parlato in passato, e la versione 10beta è ottima sul netbook: occupa meno risorse di FireFox, ha una valanga di funzionalità, ed è ACID-3 compliant. Contiene pure molti widgets (anche se non tanti come il mitico FireFox ).

Questi tools li sto usando sul mio “piccolino”, ed il tutto funziona a meraviglia.

Anche per oggi è tutto, se volete delucidazioni o approfondimenti, non avete che da chiedere! Io sono qui a vostra disposizione!

A presto!!!