mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-02-20 23:21:40 +08:00
More work on web config
This commit is contained in:
parent
8b8a970098
commit
c6c55823ac
@ -16,7 +16,8 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
|
||||
""" Run me like this: ./create_manpage_completions.py /usr/share/man/man1/* > test2.out """
|
||||
|
||||
import sys, re, os.path, gzip
|
||||
import sys, re, os.path, gzip, traceback
|
||||
|
||||
|
||||
# This gets set to the name of the command that we are currently executing
|
||||
CMDNAME = ""
|
||||
@ -51,7 +52,7 @@ def printcompletecommand(cmdname, args, description):
|
||||
def builtcommand(options, description):
|
||||
# print "Options are: ", options
|
||||
optionlist = re.split(" |,|\"|=|[|]", options)
|
||||
optionlist = filter(lambda x: len(x) > 0 and x[0] == "-", optionlist)
|
||||
optionlist = [x for x in optionlist if x.startswith('-')]
|
||||
if len(optionlist) == 0:
|
||||
return
|
||||
for i in range(0, len(optionlist)):
|
||||
@ -416,6 +417,55 @@ class Type4ManParser(ManParser):
|
||||
def name():
|
||||
return "Type4"
|
||||
|
||||
class TypeMacManParser(ManParser):
|
||||
def isMyType(self, manpage):
|
||||
options_section_matched = compileAndSearch("\.Sh DESCRIPTION", manpage)
|
||||
return options_section_matched != None
|
||||
|
||||
def trim_groff(self, line):
|
||||
# Remove initial period
|
||||
if line.startswith('.'):
|
||||
line = line[1:]
|
||||
# Skip leading groff crud
|
||||
while re.match('[A-Z][a-z]\s', line):
|
||||
line = line[3:]
|
||||
return line
|
||||
|
||||
def is_option(self, line):
|
||||
return line.startswith('.It Fl')
|
||||
|
||||
|
||||
def parseManPage(self, manpage):
|
||||
lines = manpage.splitlines()
|
||||
# Discard lines until we get to ".sh Description"
|
||||
while lines and not lines[0].startswith('.Sh DESCRIPTION'):
|
||||
lines.pop(0)
|
||||
|
||||
while lines:
|
||||
# Pop until we get to the next option
|
||||
while lines and not self.is_option(lines[0]):
|
||||
lines.pop(0)
|
||||
|
||||
# Extract the name
|
||||
name = self.trim_groff(lines.pop(0)).strip()
|
||||
|
||||
# Extract the description
|
||||
desc = ''
|
||||
while lines and not self.is_option(lines[0]):
|
||||
# print "*", lines[0]
|
||||
desc = desc + lines.pop(0)
|
||||
|
||||
#print "name: ", name
|
||||
|
||||
if name == '-':
|
||||
# Skip double -- arguments
|
||||
continue
|
||||
elif len(name) > 1:
|
||||
# Output the command
|
||||
builtcommand('--' + name, desc)
|
||||
elif len(name) == 1:
|
||||
builtcommand('-' + name, desc)
|
||||
|
||||
|
||||
def parse_manpage_at_path(manpage_path):
|
||||
filename = os.path.basename(manpage_path)
|
||||
@ -432,7 +482,7 @@ def parse_manpage_at_path(manpage_path):
|
||||
manpage = fd.read()
|
||||
fd.close()
|
||||
|
||||
parsers = [Type1ManParser(), Type2ManParser(), Type4ManParser(), Type3ManParser()]
|
||||
parsers = [Type1ManParser(), Type2ManParser(), Type4ManParser(), Type3ManParser(), TypeMacManParser()]
|
||||
parserToUse = None
|
||||
|
||||
# Get the "base" command, e.g. gcc.1.gz -> gcc
|
||||
@ -441,37 +491,21 @@ def parse_manpage_at_path(manpage_path):
|
||||
if cmd_base in ignoredcommands:
|
||||
return
|
||||
|
||||
idx = 0
|
||||
for parser in parsers:
|
||||
if parser.isMyType(manpage):
|
||||
parserToUse = parser
|
||||
# print "Type is: ", parser.name()
|
||||
break
|
||||
idx += 1
|
||||
|
||||
if parserToUse == None:
|
||||
print >> sys.stderr, manpage_path, " : Not supported"
|
||||
|
||||
elif parserToUse == parsers[0]:
|
||||
else:
|
||||
if parserToUse.parseManPage(manpage) == False:
|
||||
print >> sys.stderr, "Type1 : ", manpage_path, " is unparsable"
|
||||
print >> sys.stderr, "Type%d : %s is unparsable" % (idx, manpage_path)
|
||||
else:
|
||||
print >> sys.stderr, manpage_path, " parsed successfully"
|
||||
|
||||
elif parserToUse == parsers[1]:
|
||||
if parserToUse.parseManPage(manpage) == False:
|
||||
print >> sys.stderr, "Type2 : ", manpage_path, " is unparsable"
|
||||
else:
|
||||
print >> sys.stderr, "Type2 : ", manpage_path, " parsed successfully"
|
||||
elif parserToUse == parsers[2]:
|
||||
if parserToUse.parseManPage(manpage) == False:
|
||||
print >> sys.stderr, "Type3 : ", manpage_path, " is unparsable"
|
||||
else:
|
||||
print >> sys.stderr, manpage_path, " parsed successfully"
|
||||
|
||||
elif parserToUse == parsers[3]:
|
||||
if parserToUse.parseManPage(manpage) == False:
|
||||
print >> sys.stderr, "Type4 : ", manpage_path, " is unparsable"
|
||||
else:
|
||||
print >> sys.stderr, "Type4 :", manpage_path, " parsed successfully"
|
||||
|
||||
|
||||
|
||||
@ -489,3 +523,4 @@ if __name__ == "__main__":
|
||||
print >> sys.stderr, 'Cannot open ', manpage_path
|
||||
except:
|
||||
print >> sys.stderr, "Error parsing %s: %s" % (manpage_path, sys.exc_info()[0])
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
|
@ -14,7 +14,7 @@ cl = { re.compile(r"-[ \t]*\n[ \t\r]+" ):"",
|
||||
def header(cmd):
|
||||
print '''#
|
||||
# Command specific completions for the %s command.
|
||||
# These completions where generated from the commands
|
||||
# These completions were generated from the commands
|
||||
# man page by the make_completions.py script, but may
|
||||
# have been hand edited since.
|
||||
#
|
||||
|
@ -27,7 +27,7 @@ body {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tab, .selected_tab {
|
||||
.tab {
|
||||
border-style: groove;
|
||||
border-color: #292929;
|
||||
border-width: 2px;
|
||||
@ -40,6 +40,7 @@ body {
|
||||
width: 25%;
|
||||
float: left;
|
||||
background-color: #292929;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.selected_tab {
|
||||
@ -80,6 +81,58 @@ body {
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
function request_failed() {
|
||||
alert('Request failed');
|
||||
}
|
||||
|
||||
function switch_tab(new_tab) {
|
||||
/* Switch selected tab */
|
||||
$(".selected_tab").removeClass("selected_tab")
|
||||
$('#' + new_tab).addClass("selected_tab")
|
||||
|
||||
/* Empty master element */
|
||||
$('#master').empty()
|
||||
|
||||
/* Load something new */
|
||||
if (new_tab == 'tab_colors') {
|
||||
|
||||
req = $.ajax({
|
||||
type: "GET",
|
||||
url: "/colors/",
|
||||
success: function(data){
|
||||
$.each($.parseJSON(data), function(idx, contents) {
|
||||
var key = contents[0]
|
||||
var value = contents[1]
|
||||
create_master_element(key)
|
||||
})
|
||||
},
|
||||
fail: request_failed
|
||||
})
|
||||
|
||||
} else if (new_tab == 'tab_functions') {
|
||||
|
||||
req = $.ajax({
|
||||
type: "GET",
|
||||
url: "/functions/",
|
||||
success: function(data){
|
||||
$.each($.parseJSON(data), function(idx, contents) {
|
||||
var key = contents
|
||||
create_master_element(key)
|
||||
})
|
||||
},
|
||||
fail: request_failed
|
||||
})
|
||||
|
||||
} else if (new_tab == 'tab_variables') {
|
||||
|
||||
} else if (new_tab == 'tab_history') {
|
||||
|
||||
} else {
|
||||
alert("Unknown tab");
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/* Adds a new element to master */
|
||||
function create_master_element(contents) {
|
||||
$('<div/>', {
|
||||
@ -96,22 +149,8 @@ function create_master_element(contents) {
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#thelink').click(function() {
|
||||
|
||||
req = $.ajax({
|
||||
type: "GET",
|
||||
url: "/colors/",
|
||||
success: function(data){
|
||||
$.each($.parseJSON(data), function(idx, contents) {
|
||||
var key = contents[0]
|
||||
var value = contents[1]
|
||||
create_master_element(key)
|
||||
})
|
||||
},
|
||||
fail: function(){
|
||||
alert('fail')
|
||||
}
|
||||
})
|
||||
switch_tab('tab_colors')
|
||||
$('#thelink').click(function() {
|
||||
|
||||
})
|
||||
})
|
||||
@ -124,10 +163,10 @@ $(document).ready(function() {
|
||||
<span style="font-size: 68pt">fish</span>
|
||||
<div id="parent">
|
||||
<div id="tab_parent">
|
||||
<div class="selected_tab">colors</div>
|
||||
<div class="tab">functions</div>
|
||||
<div class="tab">variables</div>
|
||||
<div class="tab">history</div>
|
||||
<div class="tab selected_tab" id="tab_colors" onClick="javascript: switch_tab('tab_colors')">colors</div>
|
||||
<div class="tab" id="tab_functions" onClick="javascript: switch_tab('tab_functions')">functions</div>
|
||||
<div class="tab" id="tab_variables" onClick="javascript: switch_tab('tab_variables')">variables</div>
|
||||
<div class="tab" id="tab_history" onClick="javascript: switch_tab('tab_history')">history</div>
|
||||
</div>
|
||||
<div id="master">
|
||||
<!--- <div class="master_element"><span class="master_element_text">command</span></div> -->
|
||||
|
@ -4,8 +4,7 @@ import SimpleHTTPServer
|
||||
import SocketServer
|
||||
import webbrowser
|
||||
import subprocess
|
||||
import re
|
||||
import json
|
||||
import re, json, socket, sys
|
||||
|
||||
def run_fish_cmd(text):
|
||||
from subprocess import PIPE
|
||||
@ -21,14 +20,27 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
||||
out, err = run_fish_cmd('set')
|
||||
for match in re.finditer(r"fish_color_(\S+) (.+)", out):
|
||||
color_name, color_value = match.group(1, 2)
|
||||
result.append([color_name, color_value])
|
||||
result.append([color_name.strip(), color_value.strip()])
|
||||
print result
|
||||
return result
|
||||
|
||||
def do_get_functions(self):
|
||||
out, err = run_fish_cmd('functions')
|
||||
out = out.strip()
|
||||
|
||||
# Not sure why fish sometimes returns this with newlines
|
||||
if "\n" in out:
|
||||
return out.split('\n')
|
||||
else:
|
||||
return out.strip().split(', ')
|
||||
|
||||
|
||||
def do_GET(self):
|
||||
p = self.path
|
||||
if p == '/colors/':
|
||||
output = self.do_get_colors()
|
||||
elif p == '/functions/':
|
||||
output = self.do_get_functions()
|
||||
else:
|
||||
return SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
|
||||
|
||||
@ -38,14 +50,30 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
||||
self.wfile.write('\n')
|
||||
|
||||
# Output JSON
|
||||
print len(output)
|
||||
print output
|
||||
json.dump(output, self.wfile)
|
||||
|
||||
|
||||
|
||||
PORT = 8011
|
||||
Handler = FishConfigHTTPRequestHandler
|
||||
httpd = SocketServer.TCPServer(("", PORT), Handler)
|
||||
PORT = 8000
|
||||
while PORT <= 9000:
|
||||
try:
|
||||
Handler = FishConfigHTTPRequestHandler
|
||||
httpd = SocketServer.TCPServer(("", PORT), Handler)
|
||||
# Success
|
||||
break;
|
||||
except socket.error:
|
||||
type, value = sys.exc_info()[:2]
|
||||
if 'Address already in use' not in value:
|
||||
break
|
||||
PORT += 1
|
||||
|
||||
if PORT > 9000:
|
||||
print "Unable to start a web server"
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
webbrowser.open("http://localhost:%d" % PORT)
|
||||
|
||||
print "serving at port", PORT
|
||||
|
Loading…
x
Reference in New Issue
Block a user