Version française
Home     About     Download     Resources     Contact us    

This site is updated infrequently. For up-to-date information, please visit the new OCaml website at

Browse thread
Re: caml/mac + alpha
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 1996-10-23 (18:00)
From: Claudio Russo <cvr@d...>
Subject: Re: caml/mac + alpha

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> <>
Bruno.Petazzoni> Lyc. M. Berthelot 94100 SAINT-MAUR


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.


# 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
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
	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"
	switchTo $name

proc camlCompile {} {
	global camlPath

	catch {checkRunning "Caml Light" Caml camlPath} name

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

proc camlLoad {} {
	global camlPath

	catch {checkRunning "Caml Light" Caml camlPath} name

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

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

proc camlSelection {} {
	global camlPath

	catch {checkRunning "Caml Light" Caml camlPath} name

	if {[getPos] == [selEnd]} {
		message "No selection"
	switchTo $name

# 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

	switchTo $name

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 }


# 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

# 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 {