latest WIP
This commit is contained in:
3
Sublime/Antiki/.gitignore
vendored
Normal file
3
Sublime/Antiki/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*.pyc
|
||||
.DS_Store
|
||||
Antiki.sublime-settings
|
3
Sublime/Antiki/Default (OSX).sublime-keymap
Normal file
3
Sublime/Antiki/Default (OSX).sublime-keymap
Normal file
@@ -0,0 +1,3 @@
|
||||
[
|
||||
{"keys": ["super+enter"], "command": "antiki"}
|
||||
]
|
3
Sublime/Antiki/Default.sublime-commands
Normal file
3
Sublime/Antiki/Default.sublime-commands
Normal file
@@ -0,0 +1,3 @@
|
||||
[
|
||||
{"caption" : "Antiki at Cursor", "command" : "antiki"}
|
||||
]
|
3
Sublime/Antiki/Default.sublime-keymap
Normal file
3
Sublime/Antiki/Default.sublime-keymap
Normal file
@@ -0,0 +1,3 @@
|
||||
[
|
||||
{"keys": ["ctrl+enter"], "command": "antiki"}
|
||||
]
|
44
Sublime/Antiki/README.md
Normal file
44
Sublime/Antiki/README.md
Normal file
@@ -0,0 +1,44 @@
|
||||
Antiki -- a Xiki Clone for Sublime Text 2
|
||||
=========================================
|
||||
|
||||
Antiki implements a tiny subset of [Xiki][0] for [Sublime Text 2][2]. It is intended to be more portable and predictable than sophisticated combination of Xiki and @lunixboch's [SublimeXiki][1], while implementing the essential feature of executing shell commands and replacing them with output.
|
||||
|
||||
Antiki considers any line starting with `$` after zero or more tabs or spaces to be a possible command for execution. Placing your cursor on a command and pressing either "Command+Enter" or "Control-Enter" will cause Antiki to pass the command to your shell prompt, execute it, and replace a number of subquent lines with the output. Antiki will replace any lines with more indent than the command's indent, which effectively allows you to repeately run a command by returning your cursor to the original position and hitting "Command+Enter" again.
|
||||
|
||||
This makes Antiki a great tool for writing documentation, examples and working through demos.
|
||||
|
||||
## Example 1:
|
||||
|
||||
$ redis-cli info | head
|
||||
redis_version:2.4.17
|
||||
redis_git_sha1:00000000
|
||||
redis_git_dirty:0
|
||||
arch_bits:64
|
||||
multiplexing_api:kqueue
|
||||
gcc_version:4.2.1
|
||||
process_id:7818
|
||||
run_id:ac64457c11931712a94ef36a9547e624893755d1
|
||||
uptime_in_seconds:51
|
||||
uptime_in_days:0
|
||||
|
||||
## Features:
|
||||
|
||||
Antiki's insistence on being stupid and simple is its greatest advantage compared to similar implementations, making it portable, maintainable and understandable.
|
||||
|
||||
- Can execute shell commands in any buffer, not just Xiki buffers.
|
||||
- Does not require anything beyond Sublime Text itself, works out of the box in Windows and OSX.
|
||||
- Is much more predictable than [Xiki][0] or [SublimeXiki][1], since it does not try to outsmart Sublime Text.
|
||||
- Passes all commands through shell, ensuring features like piping to [JQ][3] or `grep` are easily available.
|
||||
|
||||
## Limitations:
|
||||
|
||||
Antiki does not provide [Xiki][0] menus or use Xiki helpers. It also does not support continuously updating output, and will hang until a command exits or ten seconds have passed -- for these features, the much more powerful [SublimeXiki][1] is recommended.
|
||||
|
||||
## Contributors:
|
||||
|
||||
- @efi -- bug report and fix for windows output decoding
|
||||
|
||||
[0]: http://xiki.org
|
||||
[1]: https://github.com/lunixbochs/SublimeXiki
|
||||
[2]: http://www.sublimetext.com
|
||||
[3]: http://stedolan.github.com/jq/
|
8
Sublime/Antiki/antiki.JSON-tmLanguage
Normal file
8
Sublime/Antiki/antiki.JSON-tmLanguage
Normal file
@@ -0,0 +1,8 @@
|
||||
{ "name": "Antiki",
|
||||
"scopeName": "source.antiki",
|
||||
"fileTypes": ["anti"],
|
||||
"patterns": [{"name" : "keyword", "match": "^[ \t]*[$](.*)$"},
|
||||
{"name" : "markup.quote", "match" : "^[ \t]* ([^$].*)"},
|
||||
{"name" : "markup.heading", "match" : "^[ \t]*(#.*)$" }],
|
||||
"uuid": "b92bb294-089b-43ea-b5da-45b5dcc9340a"
|
||||
}
|
106
Sublime/Antiki/antiki.py
Normal file
106
Sublime/Antiki/antiki.py
Normal file
@@ -0,0 +1,106 @@
|
||||
import sublime, sublime_plugin, re, subprocess, time, os, os.path
|
||||
|
||||
class AntikiCommand(sublime_plugin.TextCommand):
|
||||
def run(self, edit):
|
||||
antiki(self.view, edit)
|
||||
|
||||
def antiki(view, edit):
|
||||
if view.is_read_only(): return
|
||||
|
||||
base = view.file_name()
|
||||
if base is not None: base = os.path.dirname(base)
|
||||
cfg = sublime.load_settings("Antiki.sublime-settings")
|
||||
env = build_env(cfg, base=base)
|
||||
cwd = expand(cfg.get('cwd', '.'), env)
|
||||
enc = cfg.get('encoding', 'utf-8')
|
||||
|
||||
sels = view.sel()
|
||||
end = None
|
||||
|
||||
for sel in sels:
|
||||
# ensure that there is at least one following line.
|
||||
if sel.end() == view.size():
|
||||
view.insert(edit, view.size(), '\n')
|
||||
|
||||
row, _ = view.rowcol(sel.b)
|
||||
head, op, cmd = resolve_head(view, row)
|
||||
if cmd is None: continue
|
||||
indent = head + ' ' * len(op)
|
||||
end = resolve_body(view, row+1, indent)
|
||||
|
||||
out = head + op + cmd + '\n'
|
||||
out = out + '\n'.join(
|
||||
indent + line.decode(enc, 'ignore').rstrip() for line in perform_cmd(env, cwd, cmd)
|
||||
) + '\n'
|
||||
|
||||
end = replace_lines(view, edit, row, end-row, out)
|
||||
|
||||
if end is None: return # don't play with the selection..
|
||||
end = view.line(end.b)
|
||||
view.sel().clear()
|
||||
eol = end.end()
|
||||
if end.empty():
|
||||
view.insert(edit, eol, head)
|
||||
eol += len(head)
|
||||
view.sel().add(sublime.Region(eol,eol))
|
||||
|
||||
def build_env(cfg, base=None):
|
||||
env = os.environ.copy()
|
||||
env['BASE'] = str(base or env.get("HOME") or '.')
|
||||
mod = cfg.get('env', {})
|
||||
for key in mod:
|
||||
env[key] = str(expand(mod[key], env))
|
||||
return env
|
||||
|
||||
''' example:
|
||||
$ echo $BASE
|
||||
/Users/scott/Library/Application Support/Sublime Text 2/Packages/Antiki
|
||||
'''
|
||||
|
||||
def expand(val, env):
|
||||
return val.format(**env)
|
||||
|
||||
def perform_cmd(env, cwd, cmd):
|
||||
args = cmd
|
||||
pipe = subprocess.Popen(
|
||||
args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell=True, env=env, cwd=cwd
|
||||
)
|
||||
ticks = 0
|
||||
while ticks < 1000:
|
||||
ticks += 1
|
||||
time.sleep(.01)
|
||||
if pipe.poll() is not None:
|
||||
return pipe.stdout.readlines()
|
||||
pipe.kill()
|
||||
return pipe.stdout.readlines()
|
||||
|
||||
def replace_lines(view, edit, dest_row, dest_ct, src):
|
||||
dest = sublime.Region(
|
||||
view.text_point(dest_row,0),
|
||||
view.text_point(dest_row+dest_ct,0)
|
||||
)
|
||||
|
||||
view.replace(edit, dest, src)
|
||||
end = view.text_point(dest_row,0) + len(src)
|
||||
return sublime.Region(end,end)
|
||||
|
||||
rx_antiki = re.compile('^([ \t]*)([$] +)(.*)$')
|
||||
|
||||
def resolve_head(view, row):
|
||||
line = get_line(view, row)
|
||||
m = rx_antiki.match(line)
|
||||
if m: return m.groups()
|
||||
return None, None, None
|
||||
|
||||
def resolve_body(view, row, indent):
|
||||
while True:
|
||||
line = get_line(view, row)
|
||||
if not line: return row
|
||||
if not line.startswith(indent): return row
|
||||
row += 1
|
||||
|
||||
def get_line(view, row=0):
|
||||
point = view.text_point(row, 0)
|
||||
if row < 0: return None
|
||||
line = view.line(point)
|
||||
return view.substr(line).strip('\r\n')
|
37
Sublime/Antiki/antiki.tmLanguage
Normal file
37
Sublime/Antiki/antiki.tmLanguage
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>fileTypes</key>
|
||||
<array>
|
||||
<string>anti</string>
|
||||
</array>
|
||||
<key>name</key>
|
||||
<string>Antiki</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>^[ ]*[$](.*)$</string>
|
||||
<key>name</key>
|
||||
<string>keyword</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>^[ ]* ([^$].*)</string>
|
||||
<key>name</key>
|
||||
<string>markup.quote</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>^[ ]*(#.*)$</string>
|
||||
<key>name</key>
|
||||
<string>markup.heading</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>scopeName</key>
|
||||
<string>source.antiki</string>
|
||||
<key>uuid</key>
|
||||
<string>b92bb294-089b-43ea-b5da-45b5dcc9340a</string>
|
||||
</dict>
|
||||
</plist>
|
1
Sublime/Antiki/package-metadata.json
Normal file
1
Sublime/Antiki/package-metadata.json
Normal file
@@ -0,0 +1 @@
|
||||
{"url": "https://github.com/swdunlop/antiki", "version": "2013.02.23.12.42.25", "description": "A Xiki Clone for Sublime Text 2"}
|
Reference in New Issue
Block a user