Da qualche giorno ho iniziato ad usare un browser minimale, sviluppato dal gruppo di suckless.org, chiamato semplicemente "surf".
Il programma fa molto poco rispetto ai browser comunemente usati: si occupa di renderizzare le pagine e di permettere di navigare attraverso esse. Gestisce i cookies in un semplice file di testo, ma non fornisce un'interfaccia per poterli manipolare. Nessuna gestione dei segnalibri, della cache, della cronologia o degli scaricamenti e niente schede. Per questi compiti ci si appoggia a strumenti esterni. Tutto questo perché la filosofia che sta alla base del software suckless, che è la stessa che stava alla base di Unix, è che un programma debba svolgere un solo semplice compito, svolgerlo bene e dare la possibilità di essere interfacciato ad altri programmi per eventuali ulteriori funzionalità.
Tutto ciò è l'opposto dell'attuale tendenza che porta all'aumentare delle funzionalità di ogni programma, rendendoli quasi tutti dei "tuttofare" le cui funzioni si sovrappongono a vicenda, ed all'aumento di complessità del software per assecondare il desiderio dell'utente di poterlo utilizzare senza un minimo d'istruzione. Come conseguenza si ottengono software sempre più pesanti, bisognosi di risorse, complessi da mantenere e quindi ricchi di bachi e problemi di sicurezza ed impossibili da controllare. Perché non basta che il codice sia aperto per averne il controllo, se non si è in grado di comprenderlo e mantenerlo a causa dell'enorme complessità!
La configurazione del browser avviene al momento della compilazione, modificando
un semplice file config.h, la gestione dei segnalibri e della cronologia può
essere fatta tramite uno script esterno che verrà chiamato da una combinazione
di tasti definibile nel config.h. La cache su disco può essere gestita da un
caching proxy locale, come polipo, idem per il filtraggio dei cookies,
degli script e delle pubblicità usando privoxy (vedere anche la mia guida
su come configurare polipo, privoxy, pdnsd e tor). Il browser utilizzerà
automaticamente il nostro proxy, se configurate correttamente le variabili
d'ambiente http_proxy e https_proxy nello script di login.
I cookies, essendo salvati su un semplice file di testo, si possono manipolare
usando il proprio editor di testi preferito. Gli scaricamenti vengono fatti
tramite il programma curl chiamato nella finestra di un terminale. È possibile
modificare la chiamata al programma per gli scaricamenti, sostituendolo con un
altro di propria scelta, modificando il config.h.
Nel caso si volesse utilizzare la navigazione a schede, è possibile affiancare a
surf il programma tabbed, sviluppato sempre da suckless, oppure gestirle
tramite il proprio window manager (i3, ad esempio).
Per il rendering si appoggia al collaudato motore WebKit, già utilizzato da molti altri browser come Chrome, Safari, Epiphany e Rekonq.
Nella mia configurazione, ho modificato surf aggiungendo solamente la gestione di segnalibri, cronologia, url handlers (scorciatoie per ricerche in rete) e dei link hints, cioè la possibilità di evidenziare i collegamenti e poterli scegliere tramite tastiera allo stesso modo in cui è possibile fare con vimperator, vimprobable, dwb, uzbl ed altri browser che permettono la navigazione tramite tastiera e l'uso di scorciatoie che ricalcano quelle del famoso editor di testi vi.
L'unica difficoltà che ho incontrato è stata con lo script per segnalibri e cronologia, che era stato creato per la versione 0.4 di surf, mentre la versione attualmente disponibile è la 0.6.
Pubblico la versione da me modificata.
Differenze rispetto alla versione pubblicata su http://surf.suckless.org/files/bmarks_history
- Compatibile con surf 0.6
- Modificata la combinazione di tasti per le informazioni di debug, per evitare il conflitto con una combinazione già esistente.
- Modificati gli handler: sostituito duckduckgo a google e rimosso youtube. Per fare ricerche su youtube, wikipedia, google, si possono utilizzare i !bang di duckduckgo (aggiungere !yt, !w, !g, ecc alla propria stringa di ricerca).
- Modificati colori, font e posizione di dmenu per abbinarsi all'aspetto predefinito di dwm.
Bookmarks for surf
Descrizione
Questo script abilita in surf, segnalibri, url handlers e cronologia (per ricerche e url). NB: Questo script non necessita di patchare surf in alcun modo, come ad es. per le patch history e url handlers!
Scorciatoie
^d (mostra alcune informzioni di debug)
^b (salva l'url corrente)
^g (apre l'url usando l'autocompletamento)
^G (apre l'url senza l'autocompletamento)
URL handlers
Questo script implementa alcuni url handles
"d parola .." (cerca in duckduckgo la parola)
"t " (crea un tinyurl per la pagina corrente)
"w parola .." (cerca la parola in wikipedia)
"x parola .." (rimuove una voce dal file dei segnalibri)
Autore
Questo codice era originalmente di Peter John Hartman, quindi filtrato da pankake e nibble (vedere il loro bmarks) ed ora nuovamente a Peter John Hartman. Puoi ottenere l'ultima versione da http://durandus.trilidun.org/durandus/code/surf/.
NB: Il link indicato non è più raggiungibile. La versione più recente che conosco è questa, modificata da me, scaricabile da [gists.github.com][12].
Installazione
Copia il seguente codice in uno script chiamato surf.sh nel $PATH. Modifica config.h seguiendo le regole spiegate nell'intestazione.
Code
#!/bin/sh
# v. 2.0 - upgrade based on surf 4.0
# Creative Commons License. Peter John Hartman (http://individual.utoronto.ca/peterjh)
# Much thanks to nibble and pancake who have a different surf.sh script available which
# doesn't do the history bit.
#
# Update and modifications for surf 0.6 by Tichy
#
# this script does:
# * stores history of: (1) successful uri entries; (2) certain smart prefix entries, e.g., "g foobar"; (3) find entries
# * direct bookmark (via ^b)
# * information debug (via ^d)
# * smart prefixes e.g. d for duckduckgo search, t for tinyurl, etc.
# * delete (with smart prefix x)
#
# $1 = $xid
# $2 = $p = _SURF_FIND _SURF_BMARK _SURF_URI (what SETPROP sets in config.h)
#
# // replace default setprop with this one
# #define SETPROP(p, q) { .v = (char *[]){ "/bin/sh", "-c", "surf.sh $0 $1 $2", p, q, winid, NULL } }
#
# { MODKEY|GDK_SHIFT_MASK,GDK_b, spawn, SETPROP("_SURF_BMARK", "_SURF_BMARK") },
# { MODKEY, GDK_d, spawn, SETPROP("_SURF_INFO", "_SURF_INFO") },
# { MODKEY|GDK_SHIFT_MASK,GDK_g, spawn, SETPROP("_SURF_URI_RAW", "_SURF_URI_RAW") },
font='-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*'
normbgcolor='#222'
normfgcolor='#bbb'
selbgcolor='#057'
selfgcolor='#eee'
bmarks=~/.surf/history.txt
ffile=~/.surf/find.txt
pid=$1
fid=$2
xid=$3
dmenu="dmenu -nb $normbgcolor -nf $normfgcolor \
-sb $selbgcolor -sf $selfgcolor
s_get_prop() { # xprop
xprop -id $xid $1 | cut -d '"' -f 2
}
s_set_prop() { # xprop value
[ -n "$2" ] && xprop -id $xid -f $1 8s -set $1 "$2
}
s_write_f() { # file value
[ -n "$2" ] && (sed -i "\|$2|d" $1; echo "$2" >> $1)
#grep "$uri" $bmarks >/dev/null 2>&1 || echo "$uri" >> $bmarks
}
s_set_write_proper_uri() { # uri
# TODO: (xprop -spy _SURF_URI ... | while read name __ value; do echo $value; done works quite nice for eventloops)
# input is whatever the use inputed, so don't store that!
# first, clear the name field because surf doesn't sometimes
#s_set_prop WM_ICON_NAME "
# set the uri
s_set_prop _SURF_GO "$1
# get the new name
name=`s_get_prop WM_ICON_NAME`
# loop until the [10%] stuff is finished and we have a load (is this necessary?)
#while echo $name | grep "[*%\]" >/dev/null 2>&1; do
# name=`s_get_prop WM_ICON_NAME`
#done
# bail on error and don't store
#if [[ $name != "Error" ]]; then
# uri=`s_get_prop _SURF_URI`
# store to the bmarks file the OFFICIAL url (with http://whatever)
s_write_f $bmarks "$1
#grep "$uri" $bmarks >/dev/null 2>&1 || echo "$uri" >> $bmarks
#fi
}
case "$pid" in
"_SURF_INFO")
xprop -id $xid | sed 's/\t/ /g' | $dmenu -fn "$font" -l 20
;;
"_SURF_FIND")
find="`tac $ffile 2>/dev/null | $dmenu -fn "$font" -p find:`
s_set_prop _SURF_FIND "$find
s_write_f $ffile "$find
;;
"_SURF_BMARK")
uri=`s_get_prop _SURF_URI`
s_write_f $bmarks "$uri
;;
"_SURF_URI_RAW")
uri=`echo $(s_get_prop _SURF_URI) | $dmenu -fn "$font" -p "uri:"`
s_set_prop _SURF_GO "$uri
;;
"_SURF_URI")
sel=`tac $bmarks 2> /dev/null | $dmenu -fn "$font" -l 5 -p "uri [dtwx*]:"`
[ -z "$sel" ] && exit
opt=$(echo $sel | cut -d ' ' -f 1)
arg=$(echo $sel | cut -d ' ' -f 2-)
save=0
case "$opt" in
"d") # duckduckgo
uri="https://duckduckgo.com/?k7=kt&kj=kt&kl=it-it&kae=d&k1=-1&kp=-1&q=$arg
;;
"t") # tinyurl
uri="http://tinyurl.com/create.php?url=`s_get_prop _SURF_URI`
;;
"w") # wikipedia
uri="http://wikipedia.org/wiki/$arg
save=1
;;
"x") # delete
sed -i "\|$arg|d" $bmarks
exit;
;;
*)
uri="$sel
save=2
;;
esac
# only set the uri; don't write to file
[ $save -eq 0 ] && s_set_prop _SURF_GO "$uri
# set the url and write exactly what the user inputed to the file
[ $save -eq 1 ] && (s_set_prop _SURF_GO "$uri"; s_write_f $bmarks "$sel")
# try to set the uri only if it is a success
[ $save -eq 2 ] && s_set_write_proper_uri "$uri
;;
*)
echo Unknown xprop
;;
esac
Filosofia e manifesto di suckless
Filosofia
Siamo la casa di software di qualità come dwm, dmenu, st e molti altri strumenti la cui attenzione verte su semplicità, chiarezza e frugalità. La nostra filosofia è di mantenere le cose semplici, minimali ed usabili. Crediamo che questa dovrebbe diventare la corrente principale nel settore IT. Sfortunatamente, la tendenza verso software complessi, soggetti ad errore e lenti, sembra essere prevalente nell'industria del software odierna. Con i nostri progetti, intendiamo dimostrare l'opposto.
Il nostro progetto mira agli utenti avanzati e con esperienza. In contrasto col consueto mondo del software proprietario o di molti progetti open source di tendenza, che si focalizzano più sugli utenti medi e non tecnici, noi pensiamo che gli utenti esperti vengano per lo più ignorati. Ciò è particolarmente vero per le interfacce utente, come gli ambienti grafici per computer desktop, per dispositivi mobili, e nelle cosiddette "Web applications". Noi crediamo che il mercato degli utenti esperti sia un continua crescita, con ogni utente alla ricerca di soluzioni più appropriate per il proprio stile di lavoro.
Progettare software semplice ed elegante è molto più difficile che permettere a funzionaltà ad-hoc ed eccessivamente ambiziose di oscurare il codice col passare del tempo. È comunque uno scotto necessario da pagare per ottenere affidabilità e manutenibilità. Inoltre, il minimalismo spinge ad avere obiettivi ragionevoli e fattibili. Ci sforziamo di mantenere minimalismo e chiarezza per poter portare a termine lo sviluppo.
Manifesto
Molti hacker (open source) sono orgogliosi nell'ottenere grosse quantità di codice, perché essi credono che più linee di codice hanno scritto, più progresso hanno fatto. Più progresso hanno fatto, più sono esperti. Questa è semplicemente un'illusione.
Alla maggior parte degli hacker non interessa molto la qualità del codice. Per questo, quando ottengono qualcosa di funzionante che risolve un problema, si attaccano ad essa. Se questo tipo di sviluppo viene applicato allo stesso codice sorgente attraverso tutto il suo ciclo di vita, ci ritroviamo con grandi quantità di codice, una struttura del codice completamente rovinata, ed un sistema di progettazione viziato. Questo a causa della mancanza di chiarezza ed integrità concettuale nel processo di sviluppo.
La complessità del codice è la madre di software mastodontici, difficili da usare e totalmente inconsistenti. Con del codice complesso, i problemi vengono risolti in modi sub-ottimali, risorse di valore vi vengono legate per sempre, le prestazioni rallentano fino a zero, e le vulnerabilità diventano la norma. L'unica soluzione è di gettare l'intero progetto e riscriverlo daccapo.
La cattiva notizia: riscritture di qualità accadono raramente, perché gli hacker sono fieri delle grandi quantità di codice. Essi pensano di comprendere la complessità del codice, e che quindi non ci sia bisogno di riscriverlo. Essi si credono dei cervelloni, in grado di capire ciò che altri non possono nemmeno sperare di afferrare. Per questi tipi, il software complesso è l'ideale.
Le idee ingegnose sono semplici. Il software ingegnoso è semplice. La semplicità è il cuore della filosofia Unix. Più righe di codice avete rimosso, più progresso avete fatto. Più le righe di codice del vostro software si riducono, più abili siete diventati e meno il vostro software farà schifo.