From 35895540285a25747a72187473e560aedc6e2a6f Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Thu, 6 Sep 2012 01:30:26 -0700 Subject: Allow setting the prompt from web_config --- README.md | 2 +- color.cpp | 2 - share/tools/web_config/index.html | 190 ++++++++++++++++-- share/tools/web_config/sample_prompts/classic.fish | 36 ++++ .../web_config/sample_prompts/classic_git.fish | 86 ++++++++ .../web_config/sample_prompts/classic_status.fish | 47 +++++ .../web_config/sample_prompts/hyperminimalist.fish | 4 + .../web_config/sample_prompts/informative.fish | 51 +++++ .../tools/web_config/sample_prompts/lonetwin.fish | 20 ++ .../web_config/sample_prompts/minimalist.fish | 9 + share/tools/web_config/sample_prompts/nim.fish | 90 +++++++++ .../web_config/sample_prompts/pythonista.fish | 33 +++ .../web_config/sample_prompts/screen_savvy.fish | 9 + .../web_config/sample_prompts/user_host_path.fish | 13 ++ share/tools/web_config/webconfig.py | 221 ++++++++++++++++++++- 15 files changed, 788 insertions(+), 25 deletions(-) create mode 100644 share/tools/web_config/sample_prompts/classic.fish create mode 100644 share/tools/web_config/sample_prompts/classic_git.fish create mode 100644 share/tools/web_config/sample_prompts/classic_status.fish create mode 100644 share/tools/web_config/sample_prompts/hyperminimalist.fish create mode 100644 share/tools/web_config/sample_prompts/informative.fish create mode 100644 share/tools/web_config/sample_prompts/lonetwin.fish create mode 100644 share/tools/web_config/sample_prompts/minimalist.fish create mode 100644 share/tools/web_config/sample_prompts/nim.fish create mode 100644 share/tools/web_config/sample_prompts/pythonista.fish create mode 100644 share/tools/web_config/sample_prompts/screen_savvy.fish create mode 100644 share/tools/web_config/sample_prompts/user_host_path.fish diff --git a/README.md b/README.md index 79760010..339b5436 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Detailed user documentation is available by running `help` within fish, and also ## Building -fish can be built using autotools or Xcode: +fish can be built using autotools or Xcode. ### Autotools Build diff --git a/color.cpp b/color.cpp index 3b7baa89..dce115aa 100644 --- a/color.cpp +++ b/color.cpp @@ -164,11 +164,9 @@ static unsigned char term8_color_for_rgb(const unsigned char rgb[3]) { 0x000000, //Black 0xFF0000, //Red 0x00FF00, //Green - 0x725000, //Brown 0xFFFF00, //Yellow 0x0000FF, //Blue 0xFF00FF, //Magenta - 0xFF00FF, //Purple 0x00FFFF, //Cyan 0xFFFFFF, //White }; diff --git a/share/tools/web_config/index.html b/share/tools/web_config/index.html index 41c426f0..8b9c6132 100644 --- a/share/tools/web_config/index.html +++ b/share/tools/web_config/index.html @@ -38,7 +38,7 @@ body { padding-top: 15px; font-size: 17pt; text-align: center; - width: 25%; + width: 20%; background-color: #292929; cursor: pointer; } @@ -93,8 +93,9 @@ body { text-align: right; min-width: 200px; font-size: 16pt; - padding-bottom: 5px; - margin-top: -7px; + padding-bottom: 20px; + padding-top: 35px; + vertical-align: top; } #detail { @@ -316,6 +317,57 @@ img.delete_icon { color: #C8C8C8; } +.prompt_demo { + /* This is the div that holds what the prompt looks like */ + width: 100%; + background-color: black; + border-radius: 5px; + display: table; +} + +.prompt_save_button { + border-radius: 5px; + border: solid #474747 1px; + text-shadow: 0px 1px #000; + padding: 5px 8px; + font-size: 12pt; + display: inline-block; + margin-top: 12px; + background-color: #282828; + color: #DDD; + cursor: pointer; +} + +.prompt_save_button:hover { + background-color: #333; + border: solid #525252 1px; + color: #EEE; +} + +.prompt_demo_text { + white-space: pre; + line-height: 170%; + padding: 4px 12px; + font-size: 14pt; + top: 0px; + bottom: 0px; + vertical-align: middle; + display: table-cell; + height: 72px; /* this is really the min height */ +} + +.prompt_function { + /* This is the div that holds the prompt function's definition */ + width: 100%; + color: #BBB; + font-size: 10pt; +} + +.prompt_function_text { + white-space: pre-wrap; + padding: 25px 3px; +} + @@ -466,6 +518,15 @@ function master_color_for_color(color_str) { }) } +/* Update prompt_demo_text with the given text, adjusting the font */ +function set_prompt_demo_text(txt, font_size) { + /* Set the font size and the text */ + var prompt_demo_text = $('.prompt_demo_text') + prompt_demo_text.css('font-size', font_size) + prompt_demo_text.html(txt) +} + + function switch_tab(new_tab) { /* Switch selected tab */ $(".selected_tab").removeClass("selected_tab") @@ -480,6 +541,7 @@ function switch_tab(new_tab) { /* Hide some things */ $('#master_detail_table').hide() $('#detail_colorpicker').hide() + $('#detail_prompt').hide() $('#detail_function').hide() $('#data_table').hide() $('#table_filter_container').hide() @@ -508,11 +570,30 @@ function switch_tab(new_tab) { $('#detail_colorpicker').show() $('#master_detail_table').show() wants_data_table = false + } else if (new_tab == 'tab_prompt') { + /* Get rid of all sample prompts */ + sample_prompts.length = 0 + /* Color the first one blue */ + var first = true; + run_get_request('/sample_prompts/', function(sample_prompt){ + var name = sample_prompt['name'] + sample_prompts[name] = sample_prompt + var color = first ? '66F' : 'AAA' + var func = first ? select_current_prompt_master_element : select_sample_prompt_master_element; + var elem = create_master_element(name, false/* description */, color, '13pt', func) + if (first) { + elem.children('.master_element_text').css('border-bottom-color', color) + select_current_prompt_master_element(elem) + } + first = false; + }) + $('#detail_prompt').show() + $('#master_detail_table').show() } else if (new_tab == 'tab_functions') { /* Keep track of whether this is the first element */ var first = true run_get_request('/functions/', function(contents){ - elem = create_master_element(contents, false/* description */, 'AAAAAA', '11pt', select_function_master_element) + var elem = create_master_element(contents, false/* description */, 'AAAAAA', '11pt', select_function_master_element) if (first) { /* It's the first element, so select it, so something gets selected */ select_function_master_element(elem) @@ -576,7 +657,7 @@ function current_master_element_name() { } elem = elems[0] if (elem.id.indexOf('master_') != 0) { - show_error('Unknown color variable') + show_error('Unknown master variable') return '' } return elem.id.substring(7) @@ -641,6 +722,24 @@ function reflect_style() { } } +function cleanup_fish_function(contents) { + /* Replace leading tabs and groups of four spaces at the beginning of a line with two spaces. */ + lines = contents.split('\n') + rx = /^[\t ]+/ + for (var i=0; i < lines.length; i++) { + line = lines[i] + /* Get leading tabs and spaces */ + whitespace_arr = rx.exec(line) + if (whitespace_arr) { + /* Replace four spaces with two spaces, and tabs with two spaces */ + var whitespace = whitespace_arr[0] + new_whitespace = whitespace.replace(/( )|(\t)/g, ' ') + lines[i] = new_whitespace + line.slice(whitespace.length) + } + } + return lines.join('\n') +} + function select_master_element(elem) { $('.selected_master_elem').removeClass('selected_master_elem') $(elem).addClass('selected_master_elem') @@ -660,25 +759,57 @@ function select_function_master_element(elem) { what: current_master_element_name() }, function(contents){ /* Replace leading tabs and groups of four spaces at the beginning of a line with two spaces. */ - lines = contents.split('\n') - rx = /^[\t ]+/ - for (var i=0; i < lines.length; i++) { - line = lines[i] - /* Get leading tabs and spaces */ - whitespace_arr = rx.exec(line) - if (whitespace_arr) { - /* Replace four spaces with two spaces, and tabs with two spaces */ - var whitespace = whitespace_arr[0] - new_whitespace = whitespace.replace(/( )|(\t)/g, ' ') - lines[i] = new_whitespace + line.slice(whitespace.length) - } - } - munged_contents = lines.join('\n') - + munged_contents = cleanup_fish_function(contents) $('#detail_function').text(munged_contents) }); } +var sample_prompts = new Array(); + +function select_sample_prompt_master_element(elem) { + $('.prompt_save_button').show() + select_master_element(elem) + var name = current_master_element_name() + sample_prompt = sample_prompts[name] + run_post_request('/get_sample_prompt/', { + what: sample_prompt['function'] + }, function(keys_and_values){ + var prompt_func = keys_and_values['function'] + var prompt_demo = keys_and_values['demo'] + var prompt_font_size = keys_and_values['font_size'] + set_prompt_demo_text(prompt_demo, prompt_font_size) + //$('.prompt_demo_text').html(prompt_demo) + $('.prompt_function_text').text(cleanup_fish_function(prompt_func)) + }) +} + +function select_current_prompt_master_element(elem) { + $('.prompt_save_button').hide() + select_master_element(elem) + run_get_request_with_bulk_handler('/current_prompt/', function(keys_and_values){ + var prompt_func = keys_and_values['function'] + var prompt_demo = keys_and_values['demo'] + var prompt_font_size = keys_and_values['font_size'] + set_prompt_demo_text(prompt_demo, prompt_font_size) + $('.prompt_function_text').text(cleanup_fish_function(prompt_func)) + }) +} + +/* Applies the current prompt */ +function save_current_prompt() { + var name = current_master_element_name() + var sample_prompt = sample_prompts[name] + run_post_request('/set_prompt/', { + what: sample_prompt['function'] + }, function(contents){ + if (contents == "OK") { + select_current_prompt_master_element($('#master_Current')) + } else { + show_error(contents) + } + }) +} + function post_style_to_server() { style = current_style() if (! style) @@ -1220,6 +1351,9 @@ $(document).ready(function() { case '#history': tab_name = 'tab_history' break + case '#prompt': + tab_name = 'tab_prompt' + break case '#colors': default: tab_name = 'tab_colors' @@ -1237,6 +1371,7 @@ $(document).ready(function() {
colors
+
prompt
functions
variables
history
@@ -1256,6 +1391,21 @@ $(document).ready(function() {
+
+
+
+
+
+
+ + use prompt + +
+
+
+
+
+
diff --git a/share/tools/web_config/sample_prompts/classic.fish b/share/tools/web_config/sample_prompts/classic.fish new file mode 100644 index 00000000..9464b778 --- /dev/null +++ b/share/tools/web_config/sample_prompts/classic.fish @@ -0,0 +1,36 @@ +# name: Classic +function fish_prompt --description "Write out the prompt" + + # Just calculate these once, to save a few cycles when displaying the prompt + if not set -q __fish_prompt_hostname + set -g __fish_prompt_hostname (hostname|cut -d . -f 1) + end + + if not set -q __fish_prompt_normal + set -g __fish_prompt_normal (set_color normal) + end + + switch $USER + + case root + + if not set -q __fish_prompt_cwd + if set -q fish_color_cwd_root + set -g __fish_prompt_cwd (set_color $fish_color_cwd_root) + else + set -g __fish_prompt_cwd (set_color $fish_color_cwd) + end + end + + echo -n -s "$USER" @ "$__fish_prompt_hostname" ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '# ' + + case '*' + + if not set -q __fish_prompt_cwd + set -g __fish_prompt_cwd (set_color $fish_color_cwd) + end + + echo -n -s "$USER" @ "$__fish_prompt_hostname" ' ' "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" '> ' + + end +end diff --git a/share/tools/web_config/sample_prompts/classic_git.fish b/share/tools/web_config/sample_prompts/classic_git.fish new file mode 100644 index 00000000..b09fcef9 --- /dev/null +++ b/share/tools/web_config/sample_prompts/classic_git.fish @@ -0,0 +1,86 @@ +# name: Classic + Git +# author: Kevin Ballard + +function fish_prompt --description 'Write out the prompt' + + set -l last_status $status + + # Just calculate these once, to save a few cycles when displaying the prompt + if not set -q __fish_prompt_hostname + set -g __fish_prompt_hostname (hostname|cut -d . -f 1) + end + + if not set -q __fish_prompt_normal + set -g __fish_prompt_normal (set_color normal) + end + + set -l delim '>' + + switch $USER + + case root + + if not set -q __fish_prompt_cwd + if set -q fish_color_cwd_root + set -g __fish_prompt_cwd (set_color $fish_color_cwd_root) + else + set -g __fish_prompt_cwd (set_color $fish_color_cwd) + end + end + + case '*' + + if not set -q __fish_prompt_cwd + set -g __fish_prompt_cwd (set_color $fish_color_cwd) + end + + end + + set -l prompt_status + if test $last_status -ne 0 + if not set -q __fish_prompt_status + set -g __fish_prompt_status (set_color $fish_color_status) + end + set prompt_status "$__fish_prompt_status [$last_status]$__fish_prompt_normal" + end + + if not set -q __fish_prompt_user + set -g __fish_prompt_user (set_color $fish_color_user) + end + if not set -q __fish_prompt_host + set -g __fish_prompt_host (set_color $fish_color_host) + end + + echo -n -s "$__fish_prompt_user" "$USER" "$__fish_prompt_normal" @ "$__fish_prompt_host" "$__fish_prompt_hostname" "$__fish_prompt_normal" ' ' "$__fish_prompt_cwd" (prompt_pwd) (__fish_git_prompt) "$__fish_prompt_normal" "$prompt_status" "$delim" ' ' +end + +function __fish_repaint_user --on-variable fish_color_user --description "Event handler, repaint when fish_color_user changes" + if status --is-interactive + set -e __fish_prompt_user + commandline -f repaint ^/dev/null + end +end + +function __fish_repaint_host --on-variable fish_color_host --description "Event handler, repaint when fish_color_host changes" + if status --is-interactive + set -e __fish_prompt_host + commandline -f repaint ^/dev/null + end +end + +function __fish_repaint_status --on-variable fish_color_status --description "Event handler; repaint when fish_color_status changes" + if status --is-interactive + set -e __fish_prompt_status + commandline -f repaint ^/dev/null + end +end + +# initialize our new variables +# in theory this would be in a fish_prompt event, but this file isn't sourced +# until the fish_prompt function is called anyway. +if not set -q __prompt_initialized_2 + set -U fish_color_user -o green + set -U fish_color_host -o cyan + set -U fish_color_status red + set -U __prompt_initialized_2 +end diff --git a/share/tools/web_config/sample_prompts/classic_status.fish b/share/tools/web_config/sample_prompts/classic_status.fish new file mode 100644 index 00000000..a93ff9f2 --- /dev/null +++ b/share/tools/web_config/sample_prompts/classic_status.fish @@ -0,0 +1,47 @@ +# name: Classic + Status +# author: David Frascone + +function fish_prompt --description 'Write out the prompt' + # Save our status + set -l last_status $status + + set -l last_status_string "" + if [ $last_status -ne 0 ] + printf "%s(%d)%s " (set_color red --bold) $last_status (set_color normal) + end + + # Just calculate these once, to save a few cycles when displaying the prompt + if not set -q __fish_prompt_hostname + set -g __fish_prompt_hostname (hostname|cut -d . -f 1) + end + + if not set -q __fish_prompt_normal + set -g __fish_prompt_normal (set_color normal) + end + + set -l user_prompt '>' + switch $USER + # Set our root colors, if we're root :) + case root + set user_prompt '#' + if not set -q __fish_prompt_cwd + if set -q fish_color_cwd_root + set -g __fish_prompt_cwd (set_color $fish_color_cwd_root) + else + set -g __fish_prompt_cwd (set_color $fish_color_cwd) + end + end + case '*' + if not set -q __fish_prompt_cwd + set -g __fish_prompt_cwd (set_color $fish_color_cwd) + end + end + #printf '%s@%s %s%s%s# ' $USER $__fish_prompt_hostname "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" + #printf "LAST STATUS STRING: $last_status_string \n" + printf '%s@%s %s%s%s%s%s ' $USER $__fish_prompt_hostname "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" $user_prompt + +end + +function fish_title + echo $_ ' ' (prompt_pwd) +end diff --git a/share/tools/web_config/sample_prompts/hyperminimalist.fish b/share/tools/web_config/sample_prompts/hyperminimalist.fish new file mode 100644 index 00000000..0aca5508 --- /dev/null +++ b/share/tools/web_config/sample_prompts/hyperminimalist.fish @@ -0,0 +1,4 @@ +# name: Hyper Minimalist +function fish_prompt + echo -n '$ ' +end diff --git a/share/tools/web_config/sample_prompts/informative.fish b/share/tools/web_config/sample_prompts/informative.fish new file mode 100644 index 00000000..9095b740 --- /dev/null +++ b/share/tools/web_config/sample_prompts/informative.fish @@ -0,0 +1,51 @@ +# name: Informative +# http://michal.karzynski.pl/blog/2009/11/19/my-informative-shell-prompt/ + + +function fish_prompt --description 'Write out the prompt' + #Save the return status of the previous command + set stat $status + +# Just calculate these once, to save a few cycles when displaying the prompt + if not set -q __fish_prompt_hostname + set -g __fish_prompt_hostname (hostname|cut -d . -f 1) + end + +if not set -q __fish_prompt_normal + set -g __fish_prompt_normal (set_color normal) + end + +if not set -q __fish_color_blue + set -g __fish_color_blue (set_color -o blue) + end + +#Set the color for the status depending on the value + set __fish_color_status (set_color -o green) + if test $stat -gt 0 + set __fish_color_status (set_color -o red) + end + +switch $USER + +case root + +if not set -q __fish_prompt_cwd + if set -q fish_color_cwd_root + set -g __fish_prompt_cwd (set_color $fish_color_cwd_root) + else + set -g __fish_prompt_cwd (set_color $fish_color_cwd) + end + end + +printf '%s@%s %s%s%s# ' $USER $__fish_prompt_hostname "$__fish_prompt_cwd" (prompt_pwd) "$__fish_prompt_normal" + +case '*' + +if not set -q __fish_prompt_cwd + set -g __fish_prompt_cwd (set_color $fish_color_cwd) + end + +printf '[%s] %s%s@%s %s%s %s(%s)%s \f\r> ' (date "+%H:%M:%S") "$__fish_color_blue" $USER $__fish_prompt_hostname "$__fish_prompt_cwd" (pwd) "$__fish_color_status" "$stat" "$__fish_prompt_normal" + +end +end \ No newline at end of file diff --git a/share/tools/web_config/sample_prompts/lonetwin.fish b/share/tools/web_config/sample_prompts/lonetwin.fish new file mode 100644 index 00000000..67478594 --- /dev/null +++ b/share/tools/web_config/sample_prompts/lonetwin.fish @@ -0,0 +1,20 @@ +# name: lonetwin +# author: Steve + +function fish_prompt --description 'Write out the prompt' + # Just calculate these once, to save a few cycles when displaying the prompt + if not set -q __fish_prompt_hostname + set -g __fish_prompt_hostname (hostname -s) + end + + if not set -q __fish_prompt_normal + set -g __fish_prompt_normal (set_color normal) + end + + if not set -q __fish_prompt_cwd + set -g __fish_prompt_cwd (set_color $fish_color_cwd) + end + + echo -n -s "$USER" @ "$__fish_prompt_hostname" ' ' "$__fish_prompt_cwd" (prompt_pwd) (__fish_git_prompt) "$__fish_prompt_normal" '> ' + +end diff --git a/share/tools/web_config/sample_prompts/minimalist.fish b/share/tools/web_config/sample_prompts/minimalist.fish new file mode 100644 index 00000000..14cc0445 --- /dev/null +++ b/share/tools/web_config/sample_prompts/minimalist.fish @@ -0,0 +1,9 @@ +# name: Minimalist +# author: ridiculous_fish + +function fish_prompt + set_color $fish_color_cwd + echo -n (basename $PWD) + set_color normal + echo -n ' ) ' +end diff --git a/share/tools/web_config/sample_prompts/nim.fish b/share/tools/web_config/sample_prompts/nim.fish new file mode 100644 index 00000000..6eab39e6 --- /dev/null +++ b/share/tools/web_config/sample_prompts/nim.fish @@ -0,0 +1,90 @@ +# name: Nim +# author: Guilhem "Nim" Saurel − https://github.com/nim65s/dotfiles/ + +function fish_prompt + and set retc green; or set retc red + tty|grep -q tty; and set tty tty; or set tty pts + + set_color $retc + if [ $tty = tty ] + echo -n .- + else + echo -n '┬─' + end + set_color -o green + echo -n [ + if [ $USER = root ] + set_color -o red + else + set_color -o yellow + end + echo -n $USER + set_color -o white + echo -n @ + if [ -z "$SSH_CLIENT" ] + set_color -o blue + else + set_color -o cyan + end + echo -n (hostname) + set_color -o white + #echo -n :(prompt_pwd) + echo -n :(pwd|sed "s=$HOME=~=") + set_color -o green + echo -n ']' + set_color normal + set_color $retc + if [ $tty = tty ] + echo -n '-' + else + echo -n '─' + end + set_color -o green + echo -n '[' + set_color normal + set_color $retc + echo -n (date +%X) + set_color -o green + echo -n ] + + # Check if acpi exists + if not set -q __fish_nim_prompt_has_acpi + if type acpi > /dev/null + set -g __fish_nim_prompt_has_acpi '' + else + set -g __fish_nim_prompt_has_acpi '' # empty string + end + end + + if test "$__fish_nim_prompt_has_acpi" + if [ (acpi -a 2> /dev/null | grep off) ] + echo -n '─[' + set_color -o red + echo -n (acpi -b|cut -d' ' -f 4-) + set_color -o green + echo -n ']' + end + end + echo + set_color normal + for job in (jobs) + set_color $retc + if [ $tty = tty ] + echo -n '; ' + else + echo -n '│ ' + end + set_color brown + echo $job + end + set_color normal + set_color $retc + if [ $tty = tty ] + echo -n "'->" + else + echo -n '╰─>' + end + set_color -o red + echo -n '$ ' + set_color normal +end diff --git a/share/tools/web_config/sample_prompts/pythonista.fish b/share/tools/web_config/sample_prompts/pythonista.fish new file mode 100644 index 00000000..5c98e56b --- /dev/null +++ b/share/tools/web_config/sample_prompts/pythonista.fish @@ -0,0 +1,33 @@ +# name: Simple Pythonista +# author: davbo + +set normal (set_color normal) +set magenta (set_color magenta) +set yellow (set_color yellow) +set green (set_color green) +set gray (set_color -o black) + + +function fish_prompt + set_color yellow + printf '%s' (whoami) + set_color normal + printf ' at ' + + set_color magenta + printf '%s' (hostname|cut -d . -f 1) + set_color normal + printf ' in ' + + set_color $fish_color_cwd + printf '%s' (prompt_pwd) + set_color normal + + # Line 2 + echo + if test $VIRTUAL_ENV + printf "(%s) " (set_color blue)(basename $VIRTUAL_ENV)(set_color normal) + end + printf '↪ ' + set_color normal +end diff --git a/share/tools/web_config/sample_prompts/screen_savvy.fish b/share/tools/web_config/sample_prompts/screen_savvy.fish new file mode 100644 index 00000000..83c7db64 --- /dev/null +++ b/share/tools/web_config/sample_prompts/screen_savvy.fish @@ -0,0 +1,9 @@ +# name: Screen Savvy +# author: Matthias +function fish_prompt -d "Write out the prompt" + if test -z $WINDOW + printf '%s%s@%s%s%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (hostname|cut -d . -f 1) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) + else + printf '%s%s@%s%s%s(%s)%s%s%s> ' (set_color yellow) (whoami) (set_color purple) (hostname|cut -d . -f 1) (set_color white) (echo $WINDOW) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) + end +end diff --git a/share/tools/web_config/sample_prompts/user_host_path.fish b/share/tools/web_config/sample_prompts/user_host_path.fish new file mode 100644 index 00000000..c125eea0 --- /dev/null +++ b/share/tools/web_config/sample_prompts/user_host_path.fish @@ -0,0 +1,13 @@ +# name: User, Host, Path +# author: Jon Clayden + +function fish_prompt -d "Write out the prompt" + set -l home_escaped (echo -n $HOME | sed 's/\//\\\\\//g') + set -l pwd (echo -n $PWD | sed "s/^$home_escaped/~/" | sed 's/ /%20/g') + set -l prompt_symbol '' + switch $USER + case root; set prompt_symbol '#' + case '*'; set prompt_symbol '$' + end + printf "[%s@%s %s%s%s]%s " $USER (hostname -s) (set_color $fish_color_cwd) $pwd (set_color normal) $prompt_symbol +end diff --git a/share/tools/web_config/webconfig.py b/share/tools/web_config/webconfig.py index b2533753..6b124ef6 100755 --- a/share/tools/web_config/webconfig.py +++ b/share/tools/web_config/webconfig.py @@ -14,7 +14,7 @@ else: from urllib.parse import parse_qs import webbrowser import subprocess -import re, json, socket, os, sys, cgi, select, time +import re, json, socket, os, sys, cgi, select, time, glob def run_fish_cmd(text): from subprocess import PIPE @@ -97,6 +97,122 @@ def parse_bool(val): if val.startswith('t') or val.startswith('1'): return True return bool(val) +def html_color_for_ansi_color_index(val): + arr = ['black', '#AA0000', '#00AA00', '#AA5500', '#0000AA', '#AA00AA', '#00AAAA', '#AAAAAA', '#555555', '#FF5555', '#55FF55', '#FFFF55', '#5555FF', '#FF55FF', '#55FFFF', 'white', '#000000', '#00005f', '#000087', '#0000af', '#0000d7', '#0000ff', '#005f00', '#005f5f', '#005f87', '#005faf', '#005fd7', '#005fff', '#008700', '#00875f', '#008787', '#0087af', '#0087d7', '#0087ff', '#00af00', '#00af5f', '#00af87', '#00afaf', '#00afd7', '#00afff', '#00d700', '#00d75f', '#00d787', '#00d7af', '#00d7d7', '#00d7ff', '#00ff00', '#00ff5f', '#00ff87', '#00ffaf', '#00ffd7', '#00ffff', '#5f0000', '#5f005f', '#5f0087', '#5f00af', '#5f00d7', '#5f00ff', '#5f5f00', '#5f5f5f', '#5f5f87', '#5f5faf', '#5f5fd7', '#5f5fff', '#5f8700', '#5f875f', '#5f8787', '#5f87af', '#5f87d7', '#5f87ff', '#5faf00', '#5faf5f', '#5faf87', '#5fafaf', '#5fafd7', '#5fafff', '#5fd700', '#5fd75f', '#5fd787', '#5fd7af', '#5fd7d7', '#5fd7ff', '#5fff00', '#5fff5f', '#5fff87', '#5fffaf', '#5fffd7', '#5fffff', '#870000', '#87005f', '#870087', '#8700af', '#8700d7', '#8700ff', '#875f00', '#875f5f', '#875f87', '#875faf', '#875fd7', '#875fff', '#878700', '#87875f', '#878787', '#8787af', '#8787d7', '#8787ff', '#87af00', '#87af5f', '#87af87', '#87afaf', '#87afd7', '#87afff', '#87d700', '#87d75f', '#87d787', '#87d7af', '#87d7d7', '#87d7ff', '#87ff00', '#87ff5f', '#87ff87', '#87ffaf', '#87ffd7', '#87ffff', '#af0000', '#af005f', '#af0087', '#af00af', '#af00d7', '#af00ff', '#af5f00', '#af5f5f', '#af5f87', '#af5faf', '#af5fd7', '#af5fff', '#af8700', '#af875f', '#af8787', '#af87af', '#af87d7', '#af87ff', '#afaf00', '#afaf5f', '#afaf87', '#afafaf', '#afafd7', '#afafff', '#afd700', '#afd75f', '#afd787', '#afd7af', '#afd7d7', '#afd7ff', '#afff00', '#afff5f', '#afff87', '#afffaf', '#afffd7', '#afffff', '#d70000', '#d7005f', '#d70087', '#d700af', '#d700d7', '#d700ff', '#d75f00', '#d75f5f', '#d75f87', '#d75faf', '#d75fd7', '#d75fff', '#d78700', '#d7875f', '#d78787', '#d787af', '#d787d7', '#d787ff', '#d7af00', '#d7af5f', '#d7af87', '#d7afaf', '#d7afd7', '#d7afff', '#d7d700', '#d7d75f', '#d7d787', '#d7d7af', '#d7d7d7', '#d7d7ff', '#d7ff00', '#d7ff5f', '#d7ff87', '#d7ffaf', '#d7ffd7', '#d7ffff', '#ff0000', '#ff005f', '#ff0087', '#ff00af', '#ff00d7', '#ff00ff', '#ff5f00', '#ff5f5f', '#ff5f87', '#ff5faf', '#ff5fd7', '#ff5fff', '#ff8700', '#ff875f', '#ff8787', '#ff87af', '#ff87d7', '#ff87ff', '#ffaf00', '#ffaf5f', '#ffaf87', '#ffafaf', '#ffafd7', '#ffafff', '#ffd700', '#ffd75f', '#ffd787', '#ffd7af', '#ffd7d7', '#ffd7ff', '#ffff00', '#ffff5f', '#ffff87', '#ffffaf', '#ffffd7', '#ffffff', '#080808', '#121212', '#1c1c1c', '#262626', '#303030', '#3a3a3a', '#444444', '#4e4e4e', '#585858', '#626262', '#6c6c6c', '#767676', '#808080', '#8a8a8a', '#949494', '#9e9e9e', '#a8a8a8', '#b2b2b2', '#bcbcbc', '#c6c6c6', '#d0d0d0', '#dadada', '#e4e4e4', '#eeeeee'] + if val < 0 or val >= len(arr): + return '' + else: + return arr[val] + +# Function to return special ANSI escapes like exit_attribute_mode +g_special_escapes_dict = None +def get_special_ansi_escapes(): + global g_special_escapes_dict + if g_special_escapes_dict is None: + import curses + g_special_escapes_dict = {} + curses.setupterm() + + # Helper function to get a value for a tparm + def get_tparm(key): + val = None + key = curses.tigetstr("sgr0") + if key: val = curses.tparm(key) + return val + + # Just a few for now + g_special_escapes_dict['exit_attribute_mode'] = get_tparm('sgr0') + g_special_escapes_dict['bold'] = get_tparm('bold') + g_special_escapes_dict['underline'] = get_tparm('smul') + + return g_special_escapes_dict + +# Given a known ANSI escape sequence, convert it to HTML and append to the list +# Returns whether we have an open +def append_html_for_ansi_escape(full_val, result, span_open): + + # Strip off the initial \x1b[ and terminating m + val = full_val[2:-1] + + # Helper function to close a span if it's open + def close_span(): + if span_open: + result.append('') + + # term256 foreground color + match = re.match('38;5;(\d+)', val) + if match is not None: + close_span() + html_color = html_color_for_ansi_color_index(int(match.group(1))) + result.append('') + return True # span now open + + # term8 foreground color + if val in [str(x) for x in range(30, 38)]: + close_span() + html_color = html_color_for_ansi_color_index(int(val) - 30) + result.append('') + return True # span now open + + # Try special escapes + special_escapes = get_special_ansi_escapes() + if full_val == special_escapes['exit_attribute_mode']: + close_span() + return False + + # We don't handle bold or underline yet + + # Do nothing on failure + return span_open + +def strip_ansi(val): + # Make a half-assed effort to strip ANSI control sequences + # We assume that all such sequences start with 0x1b and end with m, + # which catches most cases + return re.sub("\x1b[^m]*m", '', val) + +def ansi_prompt_line_width(val): + # Given an ANSI prompt, return the length of its longest line, as in the number of characters it takes up + # Start by stripping off ANSI + stripped_val = strip_ansi(val) + + # Now count the longest line + return max([len(x) for x in stripped_val.split('\n')]) + + +def ansi_to_html(val): + # Split us up by ANSI escape sequences + # We want to catch not only the standard color codes, but also things like sgr0 + # Hence this lame check + separated = re.split(""" + ( # Capture + \x1b # Escpae + [^m]+ # One or more non-'m's + m # Literal m terminates the sequence + ) # End capture + """, val, 0, re.VERBOSE) + + # We have to HTML escape the text and convert ANSI escapes into HTML + # Collect it all into this array + result = [] + + span_open = False + + # Text is at even indexes, escape sequences at odd indexes + for i in xrange(len(separated)): + component = separated[i] + if i % 2 == 0: + # It's text, possibly empty + # Clean up other ANSI junk + result.append(cgi.escape(strip_ansi(component))) + else: + # It's an escape sequence. Close the previous escape. + span_open = append_html_for_ansi_escape(component, result, span_open) + + # Close final escape + if span_open: result.append('') + return ''.join(result) + class FishVar: """ A class that represents a variable """ def __init__(self, name, value): @@ -253,6 +369,90 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): # It's really lame that we always return success here out, err = run_fish_cmd('builtin history --save --delete -- ' + escape_fish_cmd(history_item_text)) return True + + def do_set_prompt_function(self, prompt_func): + cmd = prompt_func + '\n' + 'funcsave fish_prompt' + out, err = run_fish_cmd(cmd) + return len(err) == 0 + + def do_get_prompt(self, command_to_run, prompt_function_text): + # Return the prompt output by the given command + prompt_demo_ansi, err = run_fish_cmd(command_to_run) + prompt_demo_html = ansi_to_html(prompt_demo_ansi) + prompt_demo_font_size = self.font_size_for_ansi_prompt(prompt_demo_ansi) + return {'function': prompt_function_text, 'demo': prompt_demo_html, 'font_size': prompt_demo_font_size } + + def do_get_current_prompt(self): + # Return the current prompt + prompt_func, err = run_fish_cmd('functions fish_prompt') + return self.do_get_prompt('cd "' + initial_wd + '" ; fish_prompt', prompt_func.strip()) + + def do_get_sample_prompt(self, text): + # Return the prompt you get from the given text + cmd = text + "\n cd \"" + initial_wd + "\" \n fish_prompt\n" + return self.do_get_prompt(cmd, text.strip()) + + def parse_one_sample_prompt_hash(self, line, result_dict): + # Allow us to skip whitespace, etc. + if not line: return True + if line.isspace(): return True + + # Parse a comment hash like '# name: Classic' + match = re.match(r"#\s*(\w+?): (.+)", line, re.IGNORECASE) + if match: + key = match.group(1).strip() + value = match.group(2).strip() + result_dict[key] = value + return True + # Skip other hash comments + return line.startswith('#') + + + def read_one_sample_prompt(self, fd): + # Read one sample prompt from fd + function_lines = [] + result = {} + parsing_hashes = True + for line in fd: + # Parse hashes until parse_one_sample_prompt_hash return False + if parsing_hashes: + parsing_hashes = self.parse_one_sample_prompt_hash(line, result) + # Maybe not we're not parsing hashes, or maybe we already were not + if not parsing_hashes: + function_lines.append(line) + result['function'] = ''.join(function_lines).strip() + return result + + def do_get_sample_prompts_list(self): + result = [] + # Start with the "Current" meta-sample + result.append({'name': 'Current'}) + + # Read all of the prompts in sample_prompts + paths = glob.iglob('sample_prompts/*.fish') + for path in paths: + try: + fd = open(path) + result.append(self.read_one_sample_prompt(fd)) + fd.close() + except IOError: + # Ignore unreadable files, etc + pass + return result + + def font_size_for_ansi_prompt(self, prompt_demo_ansi): + width = ansi_prompt_line_width(prompt_demo_ansi) + # Pick a font size + if width >= 70: font_size = '8pt' + if width >= 60: font_size = '10pt' + elif width >= 50: font_size = '11pt' + elif width >= 40: font_size = '13pt' + elif width >= 30: font_size = '15pt' + elif width >= 25: font_size = '16pt' + elif width >= 20: font_size = '17pt' + else: font_size = '18pt' + return font_size + def do_GET(self): p = self.path @@ -267,6 +467,10 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): output = self.do_get_history() # end = time.time() # print "History: ", end - start + elif p == '/current_prompt/': + output = self.do_get_current_prompt() + elif p == '/sample_prompts/': + output = self.do_get_sample_prompts_list() elif re.match(r"/color/(\w+)/", p): name = re.match(r"/color/(\w+)/", p).group(1) output = self.do_get_color_for_variable(name) @@ -317,12 +521,21 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): elif p == '/get_function/': what = postvars.get('what') output = [self.do_get_function(what[0])] + elif p == '/get_sample_prompt/': + what = postvars.get('what') + output = [self.do_get_sample_prompt(what[0])] elif p == '/delete_history_item/': what = postvars.get('what') if self.do_delete_history_item(what[0]): output = ["OK"] else: output = ["Unable to delete history item"] + elif p == '/set_prompt/': + what = postvars.get('what') + if self.do_set_prompt_function(what[0]): + output = ["OK"] + else: + output = ["Unable to set prompt"] else: return SimpleHTTPServer.SimpleHTTPRequestHandler.do_POST(self) @@ -338,6 +551,10 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): """ Disable request logging """ pass +# We want to show the demo prompts in the directory from which this was invoked, +# so get the current working directory +initial_wd = os.getcwd() + # Make sure that the working directory is the one that contains the script server file, # because the document root is the working directory where = os.path.dirname(sys.argv[0]) @@ -367,7 +584,7 @@ if PORT > 9000: # Just look at the first letter initial_tab = '' if len(sys.argv) > 1: - for tab in ['functions', 'colors', 'variables', 'history']: + for tab in ['functions', 'prompt', 'colors', 'variables', 'history']: if tab.startswith(sys.argv[1]): initial_tab = '#' + tab break -- cgit v1.2.3