mirror of
https://github.com/akelge/zsh
synced 2025-07-04 21:49:05 +00:00
Added conque, terminal emulator
This commit is contained in:
304
vim/autoload/conque_term/conque_sole_wrapper.py
Normal file
304
vim/autoload/conque_term/conque_sole_wrapper.py
Normal file
@ -0,0 +1,304 @@
|
||||
# FILE: autoload/conque_term/conque_sole_wrapper.py {{{
|
||||
# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
|
||||
# WEBSITE: http://conque.googlecode.com
|
||||
# MODIFIED: 2010-11-15
|
||||
# VERSION: 2.0, for Vim 7.0
|
||||
# LICENSE:
|
||||
# Conque - Vim terminal/console emulator
|
||||
# Copyright (C) 2009-2010 Nico Raffo
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE. }}}
|
||||
|
||||
""" ConqueSoleSubprocessWrapper {{{
|
||||
|
||||
Subprocess wrapper to deal with Windows insanity. Launches console based python,
|
||||
which in turn launches originally requested command. Communicates with cosole
|
||||
python through shared memory objects.
|
||||
|
||||
}}} """
|
||||
|
||||
import ctypes
|
||||
import time
|
||||
|
||||
|
||||
class ConqueSoleWrapper():
|
||||
|
||||
# class properties {{{
|
||||
|
||||
shm_key = ''
|
||||
|
||||
# process info
|
||||
handle = None
|
||||
pid = None
|
||||
|
||||
# queue input in this bucket
|
||||
bucket = None
|
||||
|
||||
# console size
|
||||
# NOTE: columns should never change after open() is called
|
||||
lines = 24
|
||||
columns = 80
|
||||
|
||||
# shared memory objects
|
||||
shm_input = None
|
||||
shm_output = None
|
||||
shm_attributes = None
|
||||
shm_stats = None
|
||||
shm_command = None
|
||||
shm_rescroll = None
|
||||
shm_resize = None
|
||||
|
||||
# console python process
|
||||
proc = None
|
||||
|
||||
# }}}
|
||||
|
||||
#########################################################################
|
||||
# unused
|
||||
|
||||
def __init__(self): # {{{
|
||||
self.bucket = u('')
|
||||
|
||||
# }}}
|
||||
|
||||
#########################################################################
|
||||
# run communicator process which will in turn run cmd
|
||||
|
||||
def open(self, cmd, options={}, python_exe='python.exe', communicator_py='conque_sole_communicator.py'): # {{{
|
||||
|
||||
self.lines = options['LINES']
|
||||
self.columns = options['COLUMNS']
|
||||
|
||||
# create a shm key
|
||||
self.shm_key = 'mk' + str(time.time())
|
||||
|
||||
# python command
|
||||
cmd_line = '%s "%s" %s %d %d %s' % (python_exe, communicator_py, self.shm_key, int(self.columns), int(self.lines), cmd)
|
||||
|
||||
|
||||
# console window attributes
|
||||
flags = NORMAL_PRIORITY_CLASS | DETACHED_PROCESS
|
||||
si = STARTUPINFO()
|
||||
pi = PROCESS_INFORMATION()
|
||||
|
||||
# start the stupid process already
|
||||
try:
|
||||
res = ctypes.windll.kernel32.CreateProcessW(None, u(cmd_line), None, None, 0, flags, None, u('.'), ctypes.byref(si), ctypes.byref(pi))
|
||||
except:
|
||||
|
||||
raise
|
||||
|
||||
# handle
|
||||
self.pid = pi.dwProcessId
|
||||
|
||||
|
||||
|
||||
# init shared memory objects
|
||||
self.init_shared_memory(self.shm_key)
|
||||
|
||||
# }}}
|
||||
|
||||
#########################################################################
|
||||
# read output from shared memory
|
||||
|
||||
def read(self, start_line, num_lines, timeout=0): # {{{
|
||||
|
||||
# emulate timeout by sleeping timeout time
|
||||
if timeout > 0:
|
||||
read_timeout = float(timeout) / 1000
|
||||
|
||||
time.sleep(read_timeout)
|
||||
|
||||
output = []
|
||||
attributes = []
|
||||
|
||||
# get output
|
||||
for i in range(start_line, start_line + num_lines + 1):
|
||||
output.append(self.shm_output.read(self.columns, i * self.columns))
|
||||
attributes.append(self.shm_attributes.read(self.columns, i * self.columns))
|
||||
|
||||
return (output, attributes)
|
||||
|
||||
# }}}
|
||||
|
||||
#########################################################################
|
||||
# get current cursor/scroll position
|
||||
|
||||
def get_stats(self): # {{{
|
||||
|
||||
try:
|
||||
rescroll = self.shm_rescroll.read()
|
||||
if rescroll != '' and rescroll != None:
|
||||
|
||||
|
||||
|
||||
self.shm_rescroll.clear()
|
||||
|
||||
# close down old memory
|
||||
self.shm_output.close()
|
||||
self.shm_output = None
|
||||
|
||||
self.shm_attributes.close()
|
||||
self.shm_attributes = None
|
||||
|
||||
# reallocate memory
|
||||
|
||||
self.shm_output = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns * rescroll['data']['blocks'], 'output', rescroll['data']['mem_key'], True)
|
||||
self.shm_output.create('read')
|
||||
|
||||
self.shm_attributes = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns * rescroll['data']['blocks'], 'attributes', rescroll['data']['mem_key'], True, encoding='latin-1')
|
||||
self.shm_attributes.create('read')
|
||||
|
||||
stats_str = self.shm_stats.read()
|
||||
if stats_str != '':
|
||||
self.stats = stats_str
|
||||
else:
|
||||
return False
|
||||
except:
|
||||
|
||||
return False
|
||||
|
||||
return self.stats
|
||||
|
||||
# }}}
|
||||
|
||||
#########################################################################
|
||||
# get process status
|
||||
|
||||
def is_alive(self): # {{{
|
||||
if not self.shm_stats:
|
||||
return True
|
||||
|
||||
stats_str = self.shm_stats.read()
|
||||
if stats_str:
|
||||
return (stats_str['is_alive'])
|
||||
else:
|
||||
return True
|
||||
# }}}
|
||||
|
||||
#########################################################################
|
||||
# write input to shared memory
|
||||
|
||||
def write(self, text): # {{{
|
||||
|
||||
self.bucket += u(text, 'ascii', 'replace')
|
||||
|
||||
|
||||
|
||||
istr = self.shm_input.read()
|
||||
|
||||
if istr == '':
|
||||
|
||||
self.shm_input.write(self.bucket[:500])
|
||||
self.bucket = self.bucket[500:]
|
||||
|
||||
# }}}
|
||||
|
||||
#########################################################################
|
||||
# write virtual key code to shared memory using proprietary escape seq
|
||||
|
||||
def write_vk(self, vk_code): # {{{
|
||||
|
||||
seq = "\x1b[" + str(vk_code) + "VK"
|
||||
self.write(seq)
|
||||
|
||||
# }}}
|
||||
|
||||
#########################################################################
|
||||
# idle
|
||||
|
||||
def idle(self): # {{{
|
||||
|
||||
|
||||
self.shm_command.write({'cmd': 'idle', 'data': {}})
|
||||
|
||||
# }}}
|
||||
|
||||
#########################################################################
|
||||
# resume
|
||||
|
||||
def resume(self): # {{{
|
||||
|
||||
self.shm_command.write({'cmd': 'resume', 'data': {}})
|
||||
|
||||
# }}}
|
||||
|
||||
#########################################################################
|
||||
# shut it all down
|
||||
|
||||
def close(self): # {{{
|
||||
|
||||
self.shm_command.write({'cmd': 'close', 'data': {}})
|
||||
time.sleep(0.2)
|
||||
|
||||
# }}}
|
||||
|
||||
#########################################################################
|
||||
# resize console window
|
||||
|
||||
def window_resize(self, lines, columns): # {{{
|
||||
|
||||
self.lines = lines
|
||||
|
||||
# we don't shrink buffer width
|
||||
if columns > self.columns:
|
||||
self.columns = columns
|
||||
|
||||
self.shm_resize.write({'cmd': 'resize', 'data': {'width': columns, 'height': lines}})
|
||||
|
||||
# }}}
|
||||
|
||||
# ****************************************************************************
|
||||
# create shared memory objects
|
||||
|
||||
def init_shared_memory(self, mem_key): # {{{
|
||||
|
||||
self.shm_input = ConqueSoleSharedMemory(CONQUE_SOLE_INPUT_SIZE, 'input', mem_key)
|
||||
self.shm_input.create('write')
|
||||
self.shm_input.clear()
|
||||
|
||||
self.shm_output = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns, 'output', mem_key, True)
|
||||
self.shm_output.create('write')
|
||||
|
||||
self.shm_attributes = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns, 'attributes', mem_key, True, encoding='latin-1')
|
||||
self.shm_attributes.create('write')
|
||||
|
||||
self.shm_stats = ConqueSoleSharedMemory(CONQUE_SOLE_STATS_SIZE, 'stats', mem_key, serialize=True)
|
||||
self.shm_stats.create('write')
|
||||
self.shm_stats.clear()
|
||||
|
||||
self.shm_command = ConqueSoleSharedMemory(CONQUE_SOLE_COMMANDS_SIZE, 'command', mem_key, serialize=True)
|
||||
self.shm_command.create('write')
|
||||
self.shm_command.clear()
|
||||
|
||||
self.shm_resize = ConqueSoleSharedMemory(CONQUE_SOLE_RESIZE_SIZE, 'resize', mem_key, serialize=True)
|
||||
self.shm_resize.create('write')
|
||||
self.shm_resize.clear()
|
||||
|
||||
self.shm_rescroll = ConqueSoleSharedMemory(CONQUE_SOLE_RESCROLL_SIZE, 'rescroll', mem_key, serialize=True)
|
||||
self.shm_rescroll.create('write')
|
||||
self.shm_rescroll.clear()
|
||||
|
||||
return True
|
||||
|
||||
# }}}
|
||||
|
||||
# vim:foldmethod=marker
|
Reference in New Issue
Block a user