Re: caml/mac + alpha

Claudio Russo (cvr@dcs.ed.ac.uk)
Wed, 23 Oct 1996 13:12:53 +0100

Date: Wed, 23 Oct 1996 13:12:53 +0100
Message-Id: <3844.199610231212@yell.dcs.ed.ac.uk>
To: caml-list@inria.fr
Subject: Re: caml/mac + alpha
From: Claudio Russo <cvr@dcs.ed.ac.uk>

Bruno Petazzoni writes:

Bruno.Petazzoni> quelqu'un a-t-il interface' caml-light/mac avec
Bruno.Petazzoni> l'e'diteur alpha ? je n'ai pas le courage de plonger
Bruno.Petazzoni> dans TCL pour faire le travail... et je suis certain
Bruno.Petazzoni> que quelqu'un l'a de'ja` fait bien mieux que je
Bruno.Petazzoni> serais capable de le faire...

Bruno.Petazzoni> merci d'avance,

Bruno.Petazzoni> Bruno Petazzoni
Bruno.Petazzoni> <bpetazzoni@sancerre.ac-idf.jussieu.fr>
Bruno.Petazzoni> Lyc. M. Berthelot 94100 SAINT-MAUR

Hello,

Yes, I've got an interface which communicate via the clip-board.It's
quite primitive but fairly useful and also generates marks for your
function definitions. The stuff below works with Alpha.6.02.
The code isn't as clean as it should be and doesn't colorize (but see
Matias Giovannini's post for a way to add this).

Since camllight isn't scriptable by AppleScript, the way the interface
works is by, within Alpha, generating caml-light toplevel phrases and
copying them to the clipboard. Alpha then places caml-light in the foreground
and a simply paste command + enter in the caml-light input window executes
the command. It's ugly, but much better than typing things in directly...
Some menu options aren't implemented (be my guest).

Also, it would be easy to adapt this interface to work with Coq...

The code comes in portions: one to add to the existing system file modeDefs.tcl,
another to place in its own file camlMode.tcl. Read the code. Remember to
set camlPath to the appropriate value in file camlMode.tcl.

Cheers,
Claudio

# Add this to modeDefs.tcl in Tcl:SystemCode

#===============================================================================
lappend modes Caml

set dummyProc(Caml) dummyCaml
lappend modeSuffixes {*.ml} { set winMode Caml }
lappend modeSuffixes {*.mli} { set winMode Caml }
newModeVar Caml elecLBrace {1} 1
newModeVar Caml elecRBrace {1} 1
newModeVar Caml electricSemi 1 {1}
newModeVar Caml wordWrap {0} 1
##
# newModeVar Caml funcTitle {"Defs"} 0
# newModeVar Caml funcExpr {${camlPat}} 0
# newModeVar Caml funcPar 2 0
##
newModeVar Caml autoMark 1 1
newModeVar Caml sortedIsDefault 0 1

set modeMenus(Caml) {CamlMenu}

#===============================================================================
#place the following in a file calle camlMode.tcl in Tcl:SystemCode
# REMEMBER TO SET THE PATH camlPath
set camlPath "Macintosh HD:cvr:Camllight v0.61:Caml Light"

set camlParen {\(([^\)]*)\)}
set camlIdent {[a-zA-Z]([a-zA-Z0-9_]*)}
set camlTypeIdent {\'([a-zA-Z]([a-zA-Z0-9_]*))}
set camlWs {([ \n\t\l\r]+)}
set camlTypeParams "${camlWs}((${camlParen}|${camlTypeIdent})?)"
set camlType "(type|and)${camlTypeParams}"
set camlLet "let${camlWs}rec|let"
set camlPat "^(${camlLet}|${camlType}|value|and|type|exception)"

proc dummyCaml {} {}
##
# { global camlPat
# changeMode "Caml"
# uplevel #0 {
# set elecLBrace 1
# set elecRBrace 1
# set electricSemi 1
# set wordWrap 0
# set funcTitle "Defs"
# set funcExpr "${camlPat}"
# set funcPar 2
# set sortedIsDefault 0
# }
# }
##

proc camlPaste {} {
}

proc camlLaunch {} {
global camlPath

catch {checkRunning "Caml Light" Caml camlPath} name
C
if {![string length $name]} return

switchTo $name
}

proc camlInclude {} {
global camlPath

catch {checkRunning "Caml Light" Caml camlPath} name

set file [lindex [winNames] 0]
putScrap "include \"$file\";;\r"
save
switchTo $name
camlPaste
}

proc camlCompile {} {
global camlPath

catch {checkRunning "Caml Light" Caml camlPath} name

set file [lindex [winNames] 0]
putScrap "compile \"$file\";;\r"
save
switchTo $name
camlPaste
}

proc camlLoad {} {
global camlPath

catch {checkRunning "Caml Light" Caml camlPath} name

set file [lindex [winNames] 0]
putScrap "load \"$file\";;\r"
save
switchTo $name
camlPaste
}

proc camlLoadObject {} {

catch {checkRunning "Caml Light" Caml camlPath} name

set filename [lindex [winNames] 0]
set extension ""

if [regexp "(.*)\.mli" $filename] {append extension "\.zi"}

if [regexp "(.*)\.ml$" $filename] {append extension "\.zo"}

set filename [file rootname $filename]
append filename $extension

putScrap "load_object \"$filename\";;\r"

switchTo $name
camlPaste
}


proc camlSelection {} {
global camlPath

catch {checkRunning "Caml Light" Caml camlPath} name

if {[getPos] == [selEnd]} {
beep
message "No selection"
return;
}
copy
switchTo $name
camlPaste
}

# based on paraStart from fill.tcl
proc camlPhraseStart {pos} {
if {$pos == [maxPos]} {incr pos -1}
set res [search -n -f 0 -r 1 -l 0 {(\;\;)([ \t\n\f\r]*)} $pos]
if {![string length $res]} {return $pos}

return [lindex $res 1]
}

# based on paraFinish from fill.tcl
proc camlPhraseFinish {pos} {
set end [maxPos]
set res [search -n -f 1 -r 1 -l $end {(\;\;)} $pos]
if {![string length $res]} {return $end}
return [lindex $res 1]

}

proc camlSelectPhrase {} {
set pos [getPos]
set start [camlPhraseStart $pos]
set finish [camlPhraseFinish $pos]
goto $start
select $start $finish
}
proc camlNextPhrase {} {
set pos [getPos]
set end [maxPos]
set res [search -n -f 1 -r 1 -l $end {(\;\;)([ \n\t\f\r]*)} $pos]
goto [lindex $res 1]
}

proc camlPrevPhrase {} {
set pos [getPos]

if {$pos == [maxPos]} {incr pos -1}
set res [search -n -f 0 -r 1 -l 0 {(\;\;)} $pos]

goto [camlPhraseStart [expr [lindex $res 0] - 1]]
}


proc camlPhrase {} {
global camlPath

catch {checkRunning "Caml Light" Caml camlPath} name

camlSelectPhrase
copy
switchTo $name
camlPaste
}

proc CamlMarkFile {} {
global mpos
global camlPat
global camlIdent

set end [maxPos]
set pos 0
set l {}
while {![catch {search -f 1 -r 1 -m 0 -i 0 "$camlPat" $pos} res]} {
set start [lindex $res 0]
set end [nextLineStart $start]
set res [search -f 1 -r 1 -m 0 -i 0 -- "$camlIdent" [lindex $res 1]]
set text [getText [lindex $res 0] [lindex $res 1]]
set pos $end
set inds($text) [lineStart [expr $start - 1]]
}

if {[info exists inds]} {
foreach f [lsort [array names inds]] {
set next [nextLineStart $inds($f)]
setNamedMark $f $inds($f) $next $next
}
}
}

# switch from .ml to .mli window an vice versa, loading if necessary.
proc camlSwitch {} {

set name [lindex [winNames] 0]

set othername [file rootname $name]

switch [file extension $name] {".mli" {append othername ".ml"} ".ml" {append othername ".mli"}}

if [expr [lsearch -exact [winNames] $othername] + 1] {
bringToFront $othername
if [icon -q] { icon -f $othername -o }
return}

findFile
}

# borrowed from vi.tcl
proc addMode {mode modeProc modeWinFunc modeMenu} {
global modes
global modeProcs modeWinFuncTitle modeAddMenu
lappend modes $mode
set modeProcs($mode) $modeProc
set modeWinFuncTitle($mode) $modeWinFunc
set modeAddMenu($mode) $modeMenu
}

proc camlCd {} {
global camlPath

catch {checkRunning "Caml Light" Caml camlPath} name

set dir [file dirname [lindex [winNames -f] 0]]

putScrap "cd \"${dir}\";;\r"

switchTo $name
camlPaste
}

# add the mode (done manually for now to define hooks)
# addMode Caml setCamlMode "Defs" ""

# bindings
bind 'e' <C> camlPhrase Caml
bind 'c' <C> camlCompile Caml
bind 'l' <C> camlLoad Caml
bind 'o' <C> camlLoadObject Caml
bind 'p' <C> camlSelectPhrase Caml
bind 'r' <C> camlSelection Caml
bind 'i' <C> camlInclude Caml
bind 'p' <Cz> camlPrevPhrase Caml
bind 'n' <Cz> camlNextPhrase Caml
bind 'x' <C> camlSwitch Caml
bind 'm' <C> camlMarkFile Caml
bind 'd' <Cz> camlCd Caml

proc CamlMenu {} {}

set CamlMenu "Caml"

proc camlDoMenuItem {menu item} {

eval caml$item
}

menu -n $CamlMenu -m -p camlDoMenuItem {
"Include"
"Compile"
"Load"
"LoadObject"
"Phrase"
"Selection"
"(-"
"Cd"
"Launch"
"(-"
"StartUp"
"VerboseMode"
"Switch"
}