Updated fish_config prompt tab

This commit is contained in:
Siteshwar Vashisht 2013-11-09 18:26:44 +05:30
parent 9e424ed921
commit 63233655f4
5 changed files with 100 additions and 92 deletions

View File

@ -390,18 +390,34 @@ img.delete_icon {
} }
.prompt_demo { .prompt_demo {
/* This is the div that holds what the prompt looks like */ font-size: 12pt;
width: 100%; padding: 25px;
background-color: black; margin: 5px 20px 25px 20px; /* top right bottom left */
border-radius: 5px; cursor: pointer;
display: table; line-height: 1.8em;
border: solid #777 1px;
position: relative; /* so that our absolutely positioned elements work */
}
.prompt_demo_tight {
font-size: 10pt;
padding: 10px;
margin: 5px 20px 25px; /* top right bottom left */
cursor: pointer;
line-height: 1.8em;
border: solid #777 1px;
position: relative; /* so that our absolutely positioned elements work */
}
.prompt_demo_tight_selected {
border: solid #00ff00 1px;
} }
.save_button, .prompt_save_button { .save_button, .prompt_save_button {
border-radius: 5px; border-radius: 5px;
border: solid rgba(71,71,71,0.5) 1px; border: solid rgba(71,71,71,0.5) 1px;
padding: 5px 8px; padding: 5px 8px;
font-size: 12pt; font-size: 10pt;
display: inline-block; display: inline-block;
margin-top: 12px; margin-top: 12px;
background-color: rgba(128,128,128,0.2); background-color: rgba(128,128,128,0.2);
@ -412,7 +428,14 @@ img.delete_icon {
.prompt_save_button:hover { .prompt_save_button:hover {
background-color: #333; background-color: #333;
border: solid #525252 1px; border: solid #525252 1px;
color: #EEE; color: #ffffff;
}
.prompt_demo_choice_label {
margin: 5px 20px 5px;
cursor: pointer;
font-size: 12pt;
white-space: normal;
} }
.prompt_demo_text { .prompt_demo_text {
@ -428,15 +451,19 @@ img.delete_icon {
} }
.prompt_function { .prompt_function {
/* This is the div that holds the prompt function's definition */ display: block;
width: 100%; border: 1px solid #555;
color: #BBB; background-color: #181818;
font-size: 10pt; margin: 5px 20px 25px;
border-radius: 5;
} }
.prompt_function_text { .prompt_function_text {
white-space: pre-wrap; white-space: pre-wrap;
padding: 25px 3px; padding: 15px 3px;
width: 100%;
height: 25%;
overflow: auto;
} }
.external_link_img { .external_link_img {

View File

@ -66,7 +66,6 @@ controllers.controller("colorsController", function($scope, $http) {
for (name in settingNames) { for (name in settingNames) {
var postData = "what=" + settingNames[name] + "&color=" + $scope.selectedColorScheme[settingNames[name]] + "&background_color=&bold=&underline="; var postData = "what=" + settingNames[name] + "&color=" + $scope.selectedColorScheme[settingNames[name]] + "&background_color=&bold=&underline=";
$http.post("/set_color/", postData, { headers: {'Content-Type': 'application/x-www-form-urlencoded'} }).success(function(data, status, headers, config) { $http.post("/set_color/", postData, { headers: {'Content-Type': 'application/x-www-form-urlencoded'} }).success(function(data, status, headers, config) {
console.log(data);
}) })
} }
}; };
@ -77,40 +76,27 @@ controllers.controller("colorsController", function($scope, $http) {
controllers.controller("promptController", function($scope, $http) { controllers.controller("promptController", function($scope, $http) {
$scope.selectedPrompt = null; $scope.selectedPrompt = null;
$scope.fetchCurrentPrompt = function(currenttPrompt) {
$http.get("/current_prompt/").success(function(data, status, headers, config) {
currenttPrompt.function = data.function;
})};
$scope.fetchSamplePrompts= function() { $scope.fetchSamplePrompts= function() {
$http.get("/sample_prompts/").success(function(data, status, headers, config) { $http.get("/sample_prompts/").success(function(data, status, headers, config) {
$scope.samplePrompts = data; $scope.samplePrompts = data;
$scope.samplePromptsArrayArray = get_colors_as_nested_array($scope.samplePrompts, 1);
if ($scope.selectedPrompt == null) { if ($scope.selectedPrompt == null) {
$scope.selectPrompt($scope.samplePrompts[0]); $scope.selectPrompt($scope.samplePrompts[0]);
} }
})}; })};
$scope.fetchSamplePrompt = function(selectedPrompt) {
console.log("Fetcing sample prompt");
$http.post("/get_sample_prompt/","what=" + encodeURIComponent(selectedPrompt.function), { headers: {'Content-Type': 'application/x-www-form-urlencoded'} }).success(function(data, status, headers, config) {
console.log("Data is " + JSON.stringify(data[0]));
$scope.demoText= data[0].demo;
$scope.demoTextFontSize = data[0].font_size;
console.log("Demo text is " + $scope.demoText);
})};
$scope.selectPrompt = function(promptt) { $scope.selectPrompt = function(promptt) {
$scope.selectedPrompt= promptt; $scope.selectedPrompt= promptt;
if ($scope.selectedPrompt.name == "Current") {
$scope.fetchCurrentPrompt($scope.selectedPrompt);
}
$scope.fetchSamplePrompt($scope.selectedPrompt);
} }
$scope.setNewPrompt = function(selectedPrompt) { $scope.setNewPrompt = function(selectedPrompt) {
console.log("Set new prompt" + selectedPrompt);
$http.post("/set_prompt/","what=" + encodeURIComponent(selectedPrompt.function), { headers: {'Content-Type': 'application/x-www-form-urlencoded'} }).success(function(data, status, headers, config){ $http.post("/set_prompt/","what=" + encodeURIComponent(selectedPrompt.function), { headers: {'Content-Type': 'application/x-www-form-urlencoded'} }).success(function(data, status, headers, config){
console.log("Data is " + JSON.stringify(data));
// Update attributes of current prompt
$scope.samplePrompts[0].demo = selectedPrompt.demo;
$scope.samplePrompts[0].function = selectedPrompt.function;
$scope.samplePrompts[0].font_size = selectedPrompt.font_size;
})}; })};
$scope.fetchSamplePrompts(); $scope.fetchSamplePrompts();

View File

@ -8,4 +8,5 @@
</div> </div>
<div class="detail"> <div class="detail">
<div class="detail_function">{{ functionDefinition }}</div> <div class="detail_function">{{ functionDefinition }}</div>
</div>
</div> </div>

View File

@ -1,25 +1,17 @@
<div id="master_detail_table" style="display: table;"> <div style="padding: 0 10px 15px;">
<div id="master"> <div class="prompt_demo">
<div ng-repeat="prompt in samplePrompts"> <div ng-bind-html-unsafe="selectedPrompt.demo"></div>
<div id="master_{{prompt.name}}" ng-class="{'master_element': true, 'selected_master_elem': selectedPrompt == prompt}" ng-style="prompt.name=='Current' && {color: '#6666ff'} || {color: '#aaaaaa' }" ng-click="selectPrompt(prompt)"> <span class="prompt_save_button" style="position: absolute; right: 2px; bottom: 2px;" ng-click="setNewPrompt(selectedPrompt)" ng-hide="selectedPrompt == samplePrompts[0]">Use</span>
<span ng-class="{master_element_text: selectedPrompt == prompt}" ng-style="prompt.name=='Current' && {'font-size': '13pt', 'border-bottom-color': rgb(0, 6, 111) } || {'font-size': '13pt'}">{{ prompt.name }}</span>
</div>
</div>
</div> </div>
<div id="detail">
<div id="detail_prompt" style="display: block;"> <div class="prompt_function">
<div class="prompt_demo"> <div class="prompt_function_text">{{ selectedPrompt.function }}</div>
<div class="prompt_demo_text" style="font-size: {{ demoTextFontSize }};" ng-bind-html-unsafe="demoText"> </div>
</div>
</div> <div>
<div style="text-align: right" ng-show="selectedPrompt.name != 'Current'"> <div ng-repeat="prompt in samplePrompts" ng-click="selectPrompt(prompt)">
<span class="prompt_save_button" ng-click="setNewPrompt(selectedPrompt)"> use prompt </span> <div class="prompt_demo_choice_label">{{ prompt.name }}</div>
</div> <div ng-bind-html-unsafe='prompt.demo' ng-class="{'prompt_demo_tight': true, 'prompt_demo_tight_selected': prompt == selectedPrompt}"></div>
<div class="prompt_function">
<div class="prompt_function_text">
{{ selectedPrompt.function }}
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -118,7 +118,7 @@ def get_special_ansi_escapes():
import curses import curses
g_special_escapes_dict = {} g_special_escapes_dict = {}
curses.setupterm() curses.setupterm()
# Helper function to get a value for a tparm # Helper function to get a value for a tparm
def get_tparm(key): def get_tparm(key):
val = None val = None
@ -126,12 +126,12 @@ def get_special_ansi_escapes():
if key: val = curses.tparm(key) if key: val = curses.tparm(key)
if val: val = val.decode('utf-8') if val: val = val.decode('utf-8')
return val return val
# Just a few for now # Just a few for now
g_special_escapes_dict['exit_attribute_mode'] = get_tparm('sgr0') g_special_escapes_dict['exit_attribute_mode'] = get_tparm('sgr0')
g_special_escapes_dict['bold'] = get_tparm('bold') g_special_escapes_dict['bold'] = get_tparm('bold')
g_special_escapes_dict['underline'] = get_tparm('smul') g_special_escapes_dict['underline'] = get_tparm('smul')
return g_special_escapes_dict return g_special_escapes_dict
# Given a known ANSI escape sequence, convert it to HTML and append to the list # Given a known ANSI escape sequence, convert it to HTML and append to the list
@ -140,12 +140,12 @@ def append_html_for_ansi_escape(full_val, result, span_open):
# Strip off the initial \x1b[ and terminating m # Strip off the initial \x1b[ and terminating m
val = full_val[2:-1] val = full_val[2:-1]
# Helper function to close a span if it's open # Helper function to close a span if it's open
def close_span(): def close_span():
if span_open: if span_open:
result.append('</span>') result.append('</span>')
# term256 foreground color # term256 foreground color
match = re.match('38;5;(\d+)', val) match = re.match('38;5;(\d+)', val)
if match is not None: if match is not None:
@ -153,7 +153,7 @@ def append_html_for_ansi_escape(full_val, result, span_open):
html_color = html_color_for_ansi_color_index(int(match.group(1))) html_color = html_color_for_ansi_color_index(int(match.group(1)))
result.append('<span style="color: ' + html_color + '">') result.append('<span style="color: ' + html_color + '">')
return True # span now open return True # span now open
# term8 foreground color # term8 foreground color
if val in [str(x) for x in range(30, 38)]: if val in [str(x) for x in range(30, 38)]:
close_span() close_span()
@ -166,26 +166,26 @@ def append_html_for_ansi_escape(full_val, result, span_open):
if full_val == special_escapes['exit_attribute_mode']: if full_val == special_escapes['exit_attribute_mode']:
close_span() close_span()
return False return False
# We don't handle bold or underline yet # We don't handle bold or underline yet
# Do nothing on failure # Do nothing on failure
return span_open return span_open
def strip_ansi(val): def strip_ansi(val):
# Make a half-assed effort to strip ANSI control sequences # Make a half-assed effort to strip ANSI control sequences
# We assume that all such sequences start with 0x1b and end with m, # We assume that all such sequences start with 0x1b and end with m,
# which catches most cases # which catches most cases
return re.sub("\x1b[^m]*m", '', val) return re.sub("\x1b[^m]*m", '', val)
def ansi_prompt_line_width(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 # 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 # Start by stripping off ANSI
stripped_val = strip_ansi(val) stripped_val = strip_ansi(val)
# Now count the longest line # Now count the longest line
return max([len(x) for x in stripped_val.split('\n')]) return max([len(x) for x in stripped_val.split('\n')])
def ansi_to_html(val): def ansi_to_html(val):
# Split us up by ANSI escape sequences # Split us up by ANSI escape sequences
@ -200,13 +200,13 @@ def ansi_to_html(val):
) # End capture ) # End capture
""", re.VERBOSE) """, re.VERBOSE)
separated = reg.split(val) separated = reg.split(val)
# We have to HTML escape the text and convert ANSI escapes into HTML # We have to HTML escape the text and convert ANSI escapes into HTML
# Collect it all into this array # Collect it all into this array
result = [] result = []
span_open = False span_open = False
# Text is at even indexes, escape sequences at odd indexes # Text is at even indexes, escape sequences at odd indexes
for i in range(len(separated)): for i in range(len(separated)):
component = separated[i] component = separated[i]
@ -217,13 +217,13 @@ def ansi_to_html(val):
else: else:
# It's an escape sequence. Close the previous escape. # It's an escape sequence. Close the previous escape.
span_open = append_html_for_ansi_escape(component, result, span_open) span_open = append_html_for_ansi_escape(component, result, span_open)
# Close final escape # Close final escape
if span_open: result.append('</span>') if span_open: result.append('</span>')
# Remove empty elements # Remove empty elements
result = [x for x in result if x] result = [x for x in result if x]
# Clean up empty spans, the nasty way # Clean up empty spans, the nasty way
idx = len(result) - 1 idx = len(result) - 1
while idx >= 1: while idx >= 1:
@ -268,13 +268,13 @@ class FishBinding:
class BindingParser: class BindingParser:
""" Class to parse codes for bind command """ """ Class to parse codes for bind command """
#TODO: What does snext and sprevious mean ? #TODO: What does snext and sprevious mean ?
readable_keys= { "dc":"Delete", "npage": "Page Up", "ppage":"Page Down", readable_keys= { "dc":"Delete", "npage": "Page Up", "ppage":"Page Down",
"sdc": "Shift Delete", "shome": "Shift Home", "sdc": "Shift Delete", "shome": "Shift Home",
"left": "Left Arrow", "right": "Right Arrow", "left": "Left Arrow", "right": "Right Arrow",
"up": "Up Arrow", "down": "Down Arrow", "up": "Up Arrow", "down": "Down Arrow",
"sleft": "Shift Left", "sright": "Shift Right" "sleft": "Shift Left", "sright": "Shift Right"
} }
def set_buffer(self, buffer, is_key=False): def set_buffer(self, buffer, is_key=False):
""" Sets code to parse """ """ Sets code to parse """
@ -367,7 +367,7 @@ class BindingParser:
c = self.get_char() c = self.get_char()
if c == '\\': if c == '\\':
c = self.get_char() c = self.get_char()
if c == 'e': if c == 'e':
d = self.get_char() d = self.get_char()
if d == 'O': if d == 'O':
@ -392,10 +392,10 @@ class BindingParser:
elif c == 'b': elif c == 'b':
result += 'Backspace' result += 'Backspace'
else: else:
result += c result += c
else: else:
result += c result += c
if ctrl: if ctrl:
readable_command += 'CTRL - ' readable_command += 'CTRL - '
if alt: if alt:
readable_command += 'ALT - ' readable_command += 'ALT - '
@ -526,7 +526,7 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
out = out[len(greeting):] out = out[len(greeting):]
# Put all the bindings into a list # Put all the bindings into a list
bindings = [] bindings = []
binding_parser = BindingParser() binding_parser = BindingParser()
for line in out.split('\n'): for line in out.split('\n'):
@ -534,7 +534,7 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
if len(comps) < 3: if len(comps) < 3:
continue continue
if comps[1] == '-k': if comps[1] == '-k':
key_name, command = comps[2].split(' ', 2) key_name, command = comps[2].split(' ', 1)
binding_parser.set_buffer(key_name, True) binding_parser.set_buffer(key_name, True)
fish_binding = FishBinding(command=command, binding=key_name, readable_binding=binding_parser.get_readable_binding()) fish_binding = FishBinding(command=command, binding=key_name, readable_binding=binding_parser.get_readable_binding())
else: else:
@ -578,12 +578,12 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
# It's really lame that we always return success here # 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)) out, err = run_fish_cmd('builtin history --save --delete -- ' + escape_fish_cmd(history_item_text))
return True return True
def do_set_prompt_function(self, prompt_func): def do_set_prompt_function(self, prompt_func):
cmd = prompt_func + '\n' + 'funcsave fish_prompt' cmd = prompt_func + '\n' + 'funcsave fish_prompt'
out, err = run_fish_cmd(cmd) out, err = run_fish_cmd(cmd)
return len(err) == 0 return len(err) == 0
def do_get_prompt(self, command_to_run, prompt_function_text): def do_get_prompt(self, command_to_run, prompt_function_text):
# Return the prompt output by the given command # Return the prompt output by the given command
prompt_demo_ansi, err = run_fish_cmd(command_to_run) prompt_demo_ansi, err = run_fish_cmd(command_to_run)
@ -595,7 +595,7 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
# Return the current prompt # Return the current prompt
prompt_func, err = run_fish_cmd('functions fish_prompt') prompt_func, err = run_fish_cmd('functions fish_prompt')
return self.do_get_prompt('cd "' + initial_wd + '" ; fish_prompt', prompt_func.strip()) return self.do_get_prompt('cd "' + initial_wd + '" ; fish_prompt', prompt_func.strip())
def do_get_sample_prompt(self, text): def do_get_sample_prompt(self, text):
# Return the prompt you get from the given text # Return the prompt you get from the given text
cmd = text + "\n cd \"" + initial_wd + "\" \n fish_prompt\n" cmd = text + "\n cd \"" + initial_wd + "\" \n fish_prompt\n"
@ -605,7 +605,7 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
# Allow us to skip whitespace, etc. # Allow us to skip whitespace, etc.
if not line: return True if not line: return True
if line.isspace(): return True if line.isspace(): return True
# Parse a comment hash like '# name: Classic' # Parse a comment hash like '# name: Classic'
match = re.match(r"#\s*(\w+?): (.+)", line, re.IGNORECASE) match = re.match(r"#\s*(\w+?): (.+)", line, re.IGNORECASE)
if match: if match:
@ -615,8 +615,8 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
return True return True
# Skip other hash comments # Skip other hash comments
return line.startswith('#') return line.startswith('#')
def read_one_sample_prompt(self, fd): def read_one_sample_prompt(self, fd):
# Read one sample prompt from fd # Read one sample prompt from fd
function_lines = [] function_lines = []
@ -629,14 +629,16 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
# Maybe not we're not parsing hashes, or maybe we already were not # Maybe not we're not parsing hashes, or maybe we already were not
if not parsing_hashes: if not parsing_hashes:
function_lines.append(line) function_lines.append(line)
result['function'] = ''.join(function_lines).strip() func = ''.join(function_lines).strip()
return result result.update(self.do_get_sample_prompt(func))
return result
def do_get_sample_prompts_list(self): def do_get_sample_prompts_list(self):
result = [] result = []
# Start with the "Current" meta-sample # Start with the "Current" meta-sample
result.append({'name': 'Current'}) result.append({'name': 'Current'})
result[0].update(self.do_get_current_prompt())
# Read all of the prompts in sample_prompts # Read all of the prompts in sample_prompts
paths = glob.iglob('sample_prompts/*.fish') paths = glob.iglob('sample_prompts/*.fish')
for path in paths: for path in paths:
@ -648,7 +650,7 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
# Ignore unreadable files, etc # Ignore unreadable files, etc
pass pass
return result return result
def font_size_for_ansi_prompt(self, prompt_demo_ansi): def font_size_for_ansi_prompt(self, prompt_demo_ansi):
width = ansi_prompt_line_width(prompt_demo_ansi) width = ansi_prompt_line_width(prompt_demo_ansi)
# Pick a font size # Pick a font size
@ -761,7 +763,7 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def log_request(self, code='-', size='-'): def log_request(self, code='-', size='-'):
""" Disable request logging """ """ Disable request logging """
pass pass
# find fish # find fish
fish_bin_dir = os.environ.get('__fish_bin_dir') fish_bin_dir = os.environ.get('__fish_bin_dir')
fish_bin_path = None fish_bin_path = None
@ -782,7 +784,7 @@ if not fish_bin_dir:
else: else:
fish_bin_path = os.path.join(fish_bin_dir, 'fish') fish_bin_path = os.path.join(fish_bin_dir, 'fish')
if not os.access(fish_bin_path, os.X_OK): if not os.access(fish_bin_path, os.X_OK):
print("fish could not be executed at path '%s'. Is fish installed correctly?" % fish_bin_path) print("fish could not be executed at path '%s'. Is fish installed correctly?" % fish_bin_path)
sys.exit(-1) sys.exit(-1)