diff --git a/.travis.yml b/.travis.yml index 935eff4..67f72cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,6 @@ os: - linux # - osx julia: - - 0.7 - '1.0' - 1.1 - 1.2 diff --git a/Project.toml b/Project.toml index 2eca3ca..350cd68 100644 --- a/Project.toml +++ b/Project.toml @@ -1,14 +1,18 @@ name = "InteractiveCodeSearch" uuid = "54eb57ff-b09b-5185-b2f4-7a93509e494f" -version = "0.3.3-DEV" +version = "0.4.0-DEV" [deps] +Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +fzf_jll = "214eeab7-80f7-51ab-84ad-2988db7cef09" [compat] -julia = "= 0.7, 1.0" +Compat = "3.16" +fzf_jll = "0.24" +julia = "1.0" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/src/InteractiveCodeSearch.jl b/src/InteractiveCodeSearch.jl index 72fc063..318c960 100644 --- a/src/InteractiveCodeSearch.jl +++ b/src/InteractiveCodeSearch.jl @@ -45,8 +45,13 @@ export @search, @searchmethods import Pkg using Base using Base: IOError +using Compat: addenv using InteractiveUtils: edit, gen_call_with_extracted_types, methodswith +if VERSION >= v"1.3" + import fzf_jll +end + function _readandwrite(cmds) processes = open(cmds, "r+") return (processes.out, processes.in, processes) @@ -249,7 +254,8 @@ Configuration interface for `InteractiveCodeSearch`. ```julia using InteractiveCodeSearch -InteractiveCodeSearch.CONFIG.interactive_matcher = `peco` # default in terminal +InteractiveCodeSearch.CONFIG.interactive_matcher = `fzf ...` # default in terminal +InteractiveCodeSearch.CONFIG.interactive_matcher = `peco` InteractiveCodeSearch.CONFIG.interactive_matcher = `percol` InteractiveCodeSearch.CONFIG.interactive_matcher = `rofi -dmenu -i -p "🔎"` # use GUI matcher (default in non-terminal @@ -438,6 +444,8 @@ macro searchmethods(x) end const preferred_terminal = Cmd[ + # Only used in julia < 1.3 + `fzf`, `peco`, `percol`, ] @@ -469,24 +477,52 @@ function choose_preferred_command(f, commands::Vector{Cmd}) end end -# Julia 0.6 -const _preferred_terminal = preferred_terminal -const _preferred_gui = preferred_gui +function _get_fzf_cmd(options) + applicable(fzf_jll.fzf) && return `$(fzf_jll.fzf()) $options` + return fzf_jll.fzf() do cmd + cmd = `$cmd $options` + return setenv(cmd, copy(ENV)) + end +end function choose_interactive_matcher(; - preferred_terminal = _preferred_terminal, - preferred_gui = _preferred_gui, + preferred_terminal = preferred_terminal, + preferred_gui = preferred_gui, gui = need_gui()) if gui return choose_preferred_command(preferred_gui) do return preferred_gui[1] end - else + elseif VERSION < v"1.3" return choose_preferred_command(preferred_terminal) do return choose_preferred_command(preferred_gui) do return preferred_terminal[1] end end + else + preview_jl = joinpath(@__DIR__, "preview.jl") + preview_cmd = ` + $(Base.julia_cmd()) + --startup-file=no + --color=yes + --compile=min + -O0 + $preview_jl + ` + previewer = string(preview_cmd) + if startswith(previewer, '`') && endswith(previewer, '`') + previewer = previewer[2:end-1] + end + fzf_options = `` + if !occursin("--layout", get(ENV, "FZF_DEFAULT_OPTS", "")) + fzf_options = `$fzf_options --layout=reverse` + end + fzf_options = `$fzf_options --preview $(previewer * " {}")` + cmd = _get_fzf_cmd(fzf_options) + if Sys.which("pygmentize") !== nothing + cmd = addenv(cmd, "_INTERACTIVECODESEARCH_JL_HIGHLIGHTER" => "pygmentize -l jl") + end + return cmd end end @@ -496,17 +532,12 @@ function matcher_installation_tips(program::AbstractString) See https://github.com/peco/peco for how to install peco. """ elseif program == "rofi" - msg = """ + return """ See https://github.com/DaveDavenport/rofi for how to install rofi. """ else - msg = "" + return "" end - return """ - $msg - For terminal usage, `peco` is recommended. - See https://github.com/peco/peco for how to install peco. - """ end function maybe_warn_matcher(cmd = CONFIG.interactive_matcher) @@ -520,7 +551,6 @@ end function __init__() CONFIG.interactive_matcher = choose_interactive_matcher() - maybe_warn_matcher() end include("taskmanager.jl") diff --git a/src/preview.jl b/src/preview.jl new file mode 100644 index 0000000..7418864 --- /dev/null +++ b/src/preview.jl @@ -0,0 +1,52 @@ +code = ARGS[1] +code = replace(code, "⏎" => "\n") + +highlighter = nothing +highlighter_str = get(ENV, "_INTERACTIVECODESEARCH_JL_HIGHLIGHTER", nothing) +if highlighter_str !== nothing + highlighter = @eval @cmd $highlighter_str +end + +file = line = nothing +if (m = match(r"(.*) in \w+ at (.*):([0-9]+)$", code)) !== nothing + # code = String(m[1]) + file = m[2] + line = parse(Int, m[3]) + if isabspath(file) + print(basename(file), " (") + printstyled(file; color = :light_black) + println(")") + else + print(file, " ") + end + println("at line ", line) + if isfile(file) + open(pipeline(highlighter, stdin = IOBuffer(read(file)), stderr = stderr)) do io + width, height = displaysize(stdout) + for (i, str) in enumerate(eachline(io)) + if i > line + height * 2 + close(io) + break + elseif i > line - 2 + if i == line + printstyled(lpad(i, 5), " "; color = :magenta, bold = true) + printstyled(">"; color = :red) + else + print(lpad(i, 5), " ") + printstyled(":"; color = :light_black) + end + print(str) + printstyled("\u200b") # zero-width space + println() + end + end + end + exit() + end +end + +if highlighter === nothing + print(code) +else + run(pipeline(highlighter, stdin = IOBuffer(code), stdout = stdout, stderr = stderr)) +end