Skip to content

Commit

Permalink
split util.jl to separate functions that are for interactive convenience
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Apr 3, 2014
1 parent 5ea28cb commit dd60925
Show file tree
Hide file tree
Showing 5 changed files with 318 additions and 319 deletions.
3 changes: 3 additions & 0 deletions base/c.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ sigatomic_end() = ccall(:jl_sigatomic_end, Void, ())
disable_sigint(f::Function) = try sigatomic_begin(); f(); finally sigatomic_end(); end
reenable_sigint(f::Function) = try sigatomic_end(); f(); finally sigatomic_begin(); end

# flush C stdio output from external libraries
flush_cstdio() = ccall(:jl_flush_cstdio, Void, ())

function find_library{T<:ByteString, S<:ByteString}(libnames::Array{T,1}, extrapaths::Array{S,1}=ASCIIString[])
for lib in libnames
for path in extrapaths
Expand Down
306 changes: 306 additions & 0 deletions base/interactiveutil.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,306 @@
# editing

function edit(file::String, line::Integer)
if OS_NAME == :Windows || OS_NAME == :Darwin
default_editor = "open"
elseif isreadable("/etc/alternatives/editor")
default_editor = "/etc/alternatives/editor"
else
default_editor = "emacs"
end
editor = get(ENV,"JULIA_EDITOR", get(ENV,"VISUAL", get(ENV,"EDITOR", default_editor)))
if ispath(editor)
if isreadable(editor)
edpath = realpath(editor)
edname = basename(edpath)
else
error("can't find \"$editor\"")
end
else
edpath = edname = editor
end
issrc = length(file)>2 && file[end-2:end] == ".jl"
if issrc
file = find_source_file(file)
end
if beginswith(edname, "emacs")
jmode = joinpath(JULIA_HOME, "..", "..", "contrib", "julia-mode.el")
if issrc && isreadable(jmode)
run(`$edpath $file --eval "(progn
(require 'julia-mode \"$jmode\")
(julia-mode)
(goto-line $line))"`)
else
run(`$edpath $file --eval "(goto-line $line)"`)
end
elseif edname == "vim"
run(`$edpath $file +$line`)
elseif edname == "textmate" || edname == "mate"
spawn(`$edpath $file -l $line`)
elseif beginswith(edname, "subl")
spawn(`$edpath $file:$line`)
elseif OS_NAME == :Windows && (edname == "start" || edname == "open")
spawn(`start /b $file`)
elseif OS_NAME == :Darwin && (edname == "start" || edname == "open")
spawn(`open -t $file`)
elseif edname == "kate"
spawn(`$edpath $file -l $line`)
elseif edname == "nano"
run(`$edpath +$line $file`)
else
run(`$(shell_split(edpath)) $file`)
end
nothing
end
edit(file::String) = edit(file, 1)

function less(file::String, line::Integer)
pager = get(ENV, "PAGER", "less")
run(`$pager +$(line)g $file`)
end
less(file::String) = less(file, 1)

edit(f::Union(Function,DataType)) = edit(functionloc(f)...)
edit(f::Union(Function,DataType), t) = edit(functionloc(f,t)...)
less(f::Union(Function,DataType)) = less(functionloc(f)...)
less(f::Union(Function,DataType), t) = less(functionloc(f,t)...)

function edit( m::Method )
tv, decls, file, line = arg_decl_parts(m)
edit( string(file), line )
end


# clipboard copy and paste

@osx_only begin
function clipboard(x)
w,p = writesto(`pbcopy`)
print(w,x)
close(w)
wait(p)
end
clipboard() = readall(`pbpaste`)
end

@linux_only begin
_clipboardcmd = nothing
function clipboardcmd()
global _clipboardcmd
_clipboardcmd !== nothing && return _clipboardcmd
for cmd in (:xclip, :xsel)
success(`which $cmd` |> DevNull) && return _clipboardcmd = cmd
end
error("no clipboard command found, please install xsel or xclip")
end
function clipboard(x)
c = clipboardcmd()
cmd = c == :xsel ? `xsel --nodetach --input --clipboard` :
c == :xclip ? `xclip -quiet -in -selection clipboard` :
error("unexpected clipboard command: $c")
w,p = writesto(cmd)
print(w,x)
close(w)
wait(p)
end
function clipboard()
c = clipboardcmd()
cmd = c == :xsel ? `xsel --nodetach --output --clipboard` :
c == :xclip ? `xclip -quiet -out -selection clipboard` :
error("unexpected clipboard command: $c")
readall(cmd)
end
end

@windows_only begin
function clipboard(x::String)
ccall((:OpenClipboard, "user32"), stdcall, Bool, (Ptr{Void},), C_NULL)
ccall((:EmptyClipboard, "user32"), stdcall, Bool, ())
p = ccall((:GlobalAlloc, "kernel32"), stdcall, Ptr{Void}, (Uint16,Int32), 2, length(x)+1)
p = ccall((:GlobalLock, "kernel32"), stdcall, Ptr{Void}, (Ptr{Void},), p)
# write data to locked, allocated space
ccall(:memcpy, Ptr{Void}, (Ptr{Void},Ptr{Uint8},Int32), p, x, length(x)+1)
ccall((:GlobalUnlock, "kernel32"), stdcall, Void, (Ptr{Void},), p)
# set clipboard data type to 13 for Unicode text/string
p = ccall((:SetClipboardData, "user32"), stdcall, Ptr{Void}, (Uint32, Ptr{Void}), 1, p)
ccall((:CloseClipboard, "user32"), stdcall, Void, ())
end
clipboard(x) = clipboard(sprint(io->print(io,x))::ByteString)

function clipboard()
ccall((:OpenClipboard, "user32"), stdcall, Bool, (Ptr{Void},), C_NULL)
s = bytestring(ccall((:GetClipboardData, "user32"), stdcall, Ptr{Uint8}, (Uint32,), 1))
ccall((:CloseClipboard, "user32"), stdcall, Void, ())
return s
end
end

if !isdefined(:clipboard)
clipboard(x="") = error("clipboard functionality not implemented for $OS_NAME")
end

# system information

function versioninfo(io::IO=STDOUT, verbose::Bool=false)
println(io, "Julia Version $VERSION")
if !isempty(GIT_VERSION_INFO.commit_short)
println(io, "Commit $(GIT_VERSION_INFO.commit_short) ($(GIT_VERSION_INFO.date_string))")
end
if ccall(:jl_is_debugbuild, Cint, ())!=0
println(io, "DEBUG build")
end
println(io, "Platform Info:")
println(io, " System: ", Sys.OS_NAME, " (", Sys.MACHINE, ")")

cpu = Sys.cpu_info()
println(io, " CPU: ", cpu[1].model)
println(io, " WORD_SIZE: ", Sys.WORD_SIZE)
if verbose
lsb = ""
@linux_only try lsb = readchomp(`lsb_release -ds` .> DevNull) end
@windows_only try lsb = strip(readall(`$(ENV["COMSPEC"]) /c ver`)) end
if lsb != ""
println(io, " ", lsb)
end
println(io, " uname: ",readchomp(`uname -mprsv`))
println(io, "Memory: $(Sys.total_memory()/2^30) GB ($(Sys.free_memory()/2^20) MB free)")
try println(io, "Uptime: $(Sys.uptime()) sec") catch end
print(io, "Load Avg: ")
print_matrix(io, Sys.loadavg()')
println(io )
Sys.cpu_summary(io)
println(io )
end
if Base.libblas_name == "libopenblas" || blas_vendor() == :openblas
openblas_config = openblas_get_config()
println(io, " BLAS: libopenblas (", openblas_config, ")")
else
println(io, " BLAS: ",libblas_name)
end
println(io, " LAPACK: ",liblapack_name)
println(io, " LIBM: ",libm_name)
if verbose
println(io, "Environment:")
for (k,v) in ENV
if !is(match(r"JULIA|PATH|FLAG|^TERM$|HOME",bytestring(k)), nothing)
println(io, " $(k) = $(v)")
end
end
println(io )
println(io, "Package Directory: ", Pkg.dir())
Pkg.status(io)
end
end
versioninfo(verbose::Bool) = versioninfo(STDOUT,verbose)

# searching definitions

function which(f::Callable, args...)
if !isgeneric(f)
throw(ErrorException("not a generic function, no methods available"))
end
ms = methods(f, map(a->(isa(a,Type) ? Type{a} : typeof(a)), args))
isempty(ms) && throw(MethodError(f, args))
ms[1]
end

macro which(ex0)
if isa(ex0,Expr) &&
any(a->(Meta.isexpr(a,:kw) || Meta.isexpr(a,:parameters)), ex0.args)
# keyword args not used in dispatch, so just remove them
args = filter(a->!(Meta.isexpr(a,:kw) || Meta.isexpr(a,:parameters)), ex0.args)
return Expr(:call, :which, map(esc, args)...)
end
if isa(ex0, Expr) && ex0.head == :call
return Expr(:call, :which, map(esc, ex0.args)...)
end
ex = expand(ex0)
exret = Expr(:call, :error, "expression is not a function call")
if !isa(ex, Expr)
# do nothing -> error
elseif ex.head == :call
if any(e->(isa(e,Expr) && e.head==:(...)), ex0.args) &&
isa(ex.args[1],TopNode) && ex.args[1].name == :apply
exret = Expr(:call, ex.args[1], :which,
Expr(:tuple, esc(ex.args[2])),
map(esc, ex.args[3:end])...)
else
exret = Expr(:call, :which, map(esc, ex.args)...)
end
elseif ex.head == :body
a1 = ex.args[1]
if isa(a1, Expr) && a1.head == :call
a11 = a1.args[1]
if a11 == :setindex!
exret = Expr(:call, :which, a11, map(esc, a1.args[2:end])...)
end
end
elseif ex.head == :thunk
exret = Expr(:call, :error, "expression is not a function call, or is too complex for @which to analyze; "
* "break it down to simpler parts if possible")
end
exret
end

# `methodswith` -- shows a list of methods using the type given

function methodswith(t::Type, m::Module, showparents::Bool=false)
meths = Method[]
for nm in names(m)
try
mt = eval(m, nm)
d = mt.env.defs
while !is(d,())
if any(map(x -> x == t || (showparents && t <: x && x != Any && x != ANY && !isa(x, TypeVar)), d.sig))
push!(meths, d)
end
d = d.next
end
end
end
return meths
end

function methodswith(t::Type, showparents::Bool=false)
meths = Method[]
mainmod = current_module()
# find modules in Main
for nm in names(mainmod)
if isdefined(mainmod,nm)
mod = eval(mainmod, nm)
if isa(mod, Module)
meths = [meths, methodswith(t, mod, showparents)]
end
end
end
return meths
end

## file downloading ##

downloadcmd = nothing
function download(url::String, filename::String)
global downloadcmd
if downloadcmd === nothing
for checkcmd in (:curl, :wget, :fetch)
if success(`which $checkcmd` |> DevNull)
downloadcmd = checkcmd
break
end
end
end
if downloadcmd == :wget
run(`wget -O $filename $url`)
elseif downloadcmd == :curl
run(`curl -o $filename -L $url`)
elseif downloadcmd == :fetch
run(`fetch -f $filename $url`)
else
error("no download agent available; install curl, wget, or fetch")
end
filename
end
function download(url::String)
filename = tempname()
download(url, filename)
end
8 changes: 8 additions & 0 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ end
find_in_node1_path(name) = myid()==1 ?
find_in_path(name) : remotecall_fetch(1, find_in_path, name)

function find_source_file(file)
(isabspath(file) || isfile(file)) && return file
file2 = find_in_path(file)
file2 != nothing && return file2
file2 = "$JULIA_HOME/../share/julia/base/$file"
isfile(file2) ? file2 : nothing
end

# Store list of files and their load time
package_list = (ByteString=>Float64)[]
# to synchronize multiple tasks trying to require something
Expand Down
1 change: 1 addition & 0 deletions base/sysimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ include("version.jl")
include("datafmt.jl")
include("deepcopy.jl")
include("util.jl")
include("interactiveutil.jl")
include("replutil.jl")
include("test.jl")
include("meta.jl")
Expand Down
Loading

0 comments on commit dd60925

Please sign in to comment.