Skip to content

Commit

Permalink
Merge branch 'master' into sub_super
Browse files Browse the repository at this point in the history
  • Loading branch information
Luke Stagner committed May 23, 2014
2 parents b42723e + 2062ac3 commit 8713b4c
Show file tree
Hide file tree
Showing 19 changed files with 960 additions and 122 deletions.
3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ REPL improvements
* New native-Julia REPL implementation, eliminating many problems
stemming from the old GNU Readline-based REPL ([#6270]).

* Tab-substitution of LaTeX math symbols (e.g. `\alpha` by `α`) ([#6340]).
* Tab-substitution of LaTeX math symbols (e.g. `\alpha` by `α`) ([#6911]).
This also works in IJulia and in Emacs ([#6920]).

Library improvements
--------------------
Expand Down
25 changes: 15 additions & 10 deletions base/LineEdit.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module LineEdit

using Base.Terminals
using ..Terminals

import Base.Terminals: raw!, width, height, cmove, getX,
import ..Terminals: raw!, width, height, cmove, getX,
getY, clear_line, beep

import Base: ensureroom, peek, show
Expand All @@ -29,10 +29,13 @@ end
type Prompt <: TextInterface
prompt
first_prompt
prompt_color::ASCIIString
# A string or function to be printed before the prompt. May not change the length of the prompt.
# This may be used for changing the color, issuing other terminal escape codes, etc.
prompt_prefix
# Same as prefix except after the prompt
prompt_suffix
keymap_func
keymap_func_data
input_color
complete
on_enter
on_done
Expand Down Expand Up @@ -602,10 +605,12 @@ default_enter_cb(_) = true

write_prompt(terminal, s::PromptState) = write_prompt(terminal, s, s.p.prompt)
function write_prompt(terminal, s::PromptState, prompt)
write(terminal, s.p.prompt_color)
prefix = isa(s.p.prompt_prefix,Function) ? s.p.prompt_prefix() : s.p.prompt_prefix
suffix = isa(s.p.prompt_suffix,Function) ? s.p.prompt_suffix() : s.p.prompt_suffix
write(terminal, prefix)
write(terminal, prompt)
write(terminal, Base.text_colors[:normal])
write(terminal, s.p.input_color)
write(terminal, suffix)
end
write_prompt(terminal, s::ASCIIString) = write(terminal, s)

Expand Down Expand Up @@ -1269,17 +1274,17 @@ const default_keymap_func = @LineEdit.keymap [LineEdit.default_keymap, LineEdit.

function Prompt(prompt;
first_prompt = prompt,
prompt_color = "",
prompt_prefix = "",
prompt_suffix = "",
keymap_func = default_keymap_func,
keymap_func_data = nothing,
input_color = "",
complete = EmptyCompletionProvider(),
on_enter = default_enter_cb,
on_done = ()->nothing,
hist = EmptyHistoryProvider())

Prompt(prompt, first_prompt, prompt_color, keymap_func, keymap_func_data,
input_color, complete, on_enter, on_done, hist)
Prompt(prompt, first_prompt, prompt_prefix, prompt_suffix, keymap_func, keymap_func_data,
complete, on_enter, on_done, hist)
end

run_interface(::Prompt) = nothing
Expand Down
84 changes: 52 additions & 32 deletions base/REPL.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module REPL

using Base.Meta
using Base.Terminals
using Base.LineEdit
using Base.REPLCompletions
using ..Terminals
using ..LineEdit
using ..REPLCompletions

export
BasicREPL,
Expand All @@ -16,7 +16,7 @@ import Base:
display,
writemime

import Base.LineEdit:
import ..LineEdit:
CompletionProvider,
HistoryProvider,
add_history,
Expand Down Expand Up @@ -95,6 +95,7 @@ function start_repl_backend(repl_channel::RemoteRef, response_channel::RemoteRef
eval_user_input(ast, backend)
end
end
backend
end

function display_error(io::IO, er, bt)
Expand All @@ -115,8 +116,10 @@ function display(d::REPLDisplay, ::MIME"text/plain", x)
end
display(d::REPLDisplay, x) = display(d, MIME("text/plain"), x)

print_response(d::REPLDisplay, val::ANY, bt, show_value::Bool, have_color::Bool) =
print_response(outstream(d.repl), val, bt, show_value, have_color)
function print_response(repl::AbstractREPL, val::ANY, bt, show_value::Bool, have_color::Bool)
repl.waserror = bt !== nothing
print_response(outstream(repl), val, bt, show_value, have_color)
end
function print_response(errio::IO, val::ANY, bt, show_value::Bool, have_color::Bool)
while true
try
Expand Down Expand Up @@ -150,7 +153,7 @@ function run_repl(repl::AbstractREPL)
repl_channel = RemoteRef()
response_channel = RemoteRef()
start_repl_backend(repl_channel, response_channel)
run_frontend(repl, repl_channel, response_channel)
run_frontend(repl, REPLBackendRef(repl_channel,response_channel))
end

## BasicREPL ##
Expand All @@ -177,7 +180,7 @@ function run_frontend(repl::BasicREPL, repl_channel::RemoteRef, response_channel
put!(repl_channel, (ast, 1))
val, bt = take!(response_channel)
if !ends_with_semicolon(line)
print_response(d, val, bt, true, false)
print_response(repl, val, bt, true, false)
end
end
write(repl.terminal, '\n')
Expand All @@ -187,6 +190,11 @@ function run_frontend(repl::BasicREPL, repl_channel::RemoteRef, response_channel
popdisplay(d)
end

immutable REPLBackendRef
repl_channel::RemoteRef
response_channel::RemoteRef
end

## LineEditREPL ##

type LineEditREPL <: AbstractREPL
Expand All @@ -200,6 +208,11 @@ type LineEditREPL <: AbstractREPL
in_shell::Bool
in_help::Bool
consecutive_returns::Int
waserror::Bool
interface
backendref::REPLBackendRef
LineEditREPL(t,prompt_color,input_color,answer_color,shell_color,help_color,no_history_file,in_shell,in_help) =
new(t,prompt_color,input_color,answer_color,shell_color,help_color,no_history_file,in_shell,in_help,0,false)
end
outstream(r::LineEditREPL) = r.t

Expand All @@ -208,7 +221,7 @@ LineEditREPL(t::TextTerminal) = LineEditREPL(t, julia_green,
Base.answer_color(),
Base.text_colors[:red],
Base.text_colors[:yellow],
false, false, false, 0)
false, false, false)

type REPLCompletionProvider <: CompletionProvider
r::LineEditREPL
Expand Down Expand Up @@ -455,38 +468,41 @@ function find_hist_file()
end
end

backend(r::AbstractREPL) = r.backendref

send_to_backend(ast, backend::REPLBackendRef) = send_to_backend(ast, backend.repl_channel, backend.response_channel)
function send_to_backend(ast, req, rep)
put!(req, (ast, 1))
val, bt = take!(rep)
end

have_color(s) = true

function respond(f, d, main, req, rep)
function respond(f, repl, main)
(s,buf,ok)->begin
if !ok
return transition(s, :abort)
end
line = takebuf_string(buf)
if !isempty(line)
reset(d)
val, bt = send_to_backend(f(line), req, rep)
reset(repl)
val, bt = send_to_backend(f(line), backend(repl))
if !ends_with_semicolon(line) || bt !== nothing
print_response(d, val, bt, true, have_color(s))
print_response(repl, val, bt, true, have_color(s))
end
end
println(d.repl.t)
println(repl.t)
reset_state(s)
transition(s, main)
end
end

function reset(d::REPLDisplay{LineEditREPL})
raw!(d.repl.t, false)
print(Base.text_colors[:normal])
function reset(repl::LineEditREPL)
raw!(repl.t, false)
print(repl.t,Base.text_colors[:normal])
end

function setup_interface(d::REPLDisplay, req, rep; extra_repl_keymap = Dict{Any,Any}[])
function setup_interface(repl::LineEditREPL; extra_repl_keymap = Dict{Any,Any}[])
###
#
# This function returns the main interface that describes the REPL
Expand All @@ -513,43 +529,41 @@ function setup_interface(d::REPLDisplay, req, rep; extra_repl_keymap = Dict{Any,

############################### Stage I ################################

repl = d.repl

# This will provide completions for REPL and help mode
replc = REPLCompletionProvider(repl)

# Set up the main Julia prompt
main_prompt = Prompt("julia> ";
# Copy colors from the prompt object
prompt_color = repl.prompt_color,
input_color = repl.input_color,
prompt_prefix = repl.prompt_color,
prompt_suffix = repl.input_color,
keymap_func_data = repl,
complete = replc,
on_enter = s->return_callback(repl, s))

main_prompt.on_done = respond(Base.parse_input_line, d, main_prompt, req, rep)
main_prompt.on_done = respond(Base.parse_input_line, repl, main_prompt)

# Setup help mode
help_mode = Prompt(" help> ",
prompt_color = repl.help_color,
input_color = repl.input_color,
prompt_prefix = repl.help_color,
prompt_suffix = repl.input_color,
keymap_func_data = repl,
complete = replc,
# When we're done transform the entered line into a call to help("$line")
on_done = respond(d, main_prompt, req, rep) do line
on_done = respond(repl, main_prompt) do line
parse("Base.@help $line", raise=false)
end)

# Set up shell mode
shell_mode = Prompt("shell> ";
prompt_color = repl.shell_color,
input_color = repl.input_color,
prompt_prefix = repl.shell_color,
prompt_suffix = repl.input_color,
keymap_func_data = repl,
complete = ShellCompletionProvider(repl),
# Transform "foo bar baz" into `foo bar baz` (shell quoting)
# and pass into Base.repl_cmd for processing (handles `ls` and `cd`
# special)
on_done = respond(d, main_prompt, req, rep) do line
on_done = respond(repl, main_prompt) do line
Expr(:call, :(Base.repl_cmd), macroexpand(Expr(:macrocall, symbol("@cmd"),line)))
end)

Expand Down Expand Up @@ -684,10 +698,16 @@ function setup_interface(d::REPLDisplay, req, rep; extra_repl_keymap = Dict{Any,
ModalInterface([main_prompt, shell_mode, help_mode,hkp])
end

function run_frontend(repl::LineEditREPL, repl_channel, response_channel)
function run_frontend(repl::LineEditREPL, backend)
d = REPLDisplay(repl)
pushdisplay(d)
run_interface(repl.t, setup_interface(d, repl_channel, response_channel))
if !isdefined(repl,:interface)
interface = repl.interface = setup_interface(repl)
else
interface = repl.interface
end
repl.backendref = backend
run_interface(repl.t, interface)
popdisplay(d)
end

Expand Down Expand Up @@ -758,7 +778,7 @@ function run_frontend(repl::StreamREPL, repl_channel, response_channel)
put!(repl_channel, (ast, 1))
val, bt = take!(response_channel)
if !ends_with_semicolon(line)
print_response(d, val, bt, true, have_color)
print_response(repl, val, bt, true, have_color)
end
end
end
Expand Down
14 changes: 8 additions & 6 deletions base/REPLCompletions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,6 @@ function completions(string, pos)
paths[1] *= "\""
end
return sort(paths), r, true
elseif inc_tag == :other && string[pos] == '('
endpos = prevind(string, pos)
startpos = nextind(string, rsearch(string, non_identifier_chars, endpos))
return complete_methods(string[startpos:endpos]), startpos:endpos, false
elseif inc_tag == :comment
return UTF8String[], 0:-1, false
end

slashpos = rsearch(string, '\\', pos)
Expand All @@ -182,6 +176,14 @@ function completions(string, pos)
end
end

if inc_tag == :other && string[pos] == '('
endpos = prevind(string, pos)
startpos = nextind(string, rsearch(string, non_identifier_chars, endpos))
return complete_methods(string[startpos:endpos]), startpos:endpos, false
elseif inc_tag == :comment
return UTF8String[], 0:-1, false
end

dotpos = rsearch(string, '.', pos)
startpos = nextind(string, rsearch(string, non_identifier_chars, pos))

Expand Down
19 changes: 10 additions & 9 deletions base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ function _start()
(quiet,repl,startup,color_set,no_history_file) = process_options(copy(ARGS))

local term
global active_repl
if repl
if !isa(STDIN,TTY)
global is_interactive |= !isa(STDIN,Union(File,IOStream))
Expand All @@ -362,6 +363,14 @@ function _start()
term = Terminals.TTYTerminal(get(ENV,"TERM",@windows? "" : "dumb"),STDIN,STDOUT,STDERR)
global is_interactive = true
color_set || (global have_color = Terminals.hascolor(term))
if term.term_type == "dumb"
active_repl = REPL.BasicREPL(term)
else
active_repl = REPL.LineEditREPL(term)
active_repl.no_history_file = no_history_file
end

quiet || REPL.banner(term,term)
end
end

Expand All @@ -384,15 +393,7 @@ function _start()
end
quit()
end
quiet || REPL.banner(term,term)
local repl
if term.term_type == "dumb"
repl = REPL.BasicREPL(term)
else
repl = REPL.LineEditREPL(term)
repl.no_history_file = no_history_file
end
REPL.run_repl(repl)
REPL.run_repl(active_repl)
end
catch err
display_error(err,catch_backtrace())
Expand Down
4 changes: 3 additions & 1 deletion base/latex_symbols.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ const latex_symbols = [
"\\hbar" => "ħ",
"\\del" => "",

"\\sout" => "̶",# ulem package, same as Elzbar
"\\euro" => "",

# 732 symbols generated from unicode.xml
"\\textexclamdown" => "¡",
"\\sterling" => "£",
Expand Down Expand Up @@ -829,5 +832,4 @@ const latex_symbols = [
"\\overbrace" => "",
"\\underbrace" => "",


]
7 changes: 7 additions & 0 deletions base/libc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ function strptime(fmt::String, timestr::String)
if r == C_NULL
error("invalid arguments")
end
@osx_only begin
# if we didn't explicitly parse the weekday or year day, use mktime
# to fill them in automatically.
if !ismatch(r"([^%]|^)%(a|A|j|w|Ow)", fmt)
ccall(:mktime, Int, (Ptr{Void},), &tm)
end
end
tm
end

Expand Down
Loading

0 comments on commit 8713b4c

Please sign in to comment.