allow utf-8 data in error msgs, etc
--HG-- branch : pmacs2
This commit is contained in:
parent
348e6eee2a
commit
3ac5fe7775
|
@ -526,9 +526,9 @@ class Application(object):
|
||||||
self.error_timestamp = time.time()
|
self.error_timestamp = time.time()
|
||||||
def set_error(self, s):
|
def set_error(self, s):
|
||||||
self.set_msg(s)
|
self.set_msg(s)
|
||||||
self.log.append_lines([s, ""], act=buffer.ACT_NONE, force=True)
|
self.log.append_lines([s, u""], act=buffer.ACT_NONE, force=True)
|
||||||
def clear_error(self):
|
def clear_error(self):
|
||||||
self.error_string = ""
|
self.error_string = u""
|
||||||
self.error_timestamp = None
|
self.error_timestamp = None
|
||||||
def try_manual_resize(self):
|
def try_manual_resize(self):
|
||||||
y, x = self.stdscr.getmaxyx()
|
y, x = self.stdscr.getmaxyx()
|
||||||
|
@ -607,6 +607,9 @@ class Application(object):
|
||||||
else:
|
else:
|
||||||
self.highlight_mark = False
|
self.highlight_mark = False
|
||||||
|
|
||||||
|
def addstr(self, y, x, s, attr=curses.A_NORMAL):
|
||||||
|
self.win.addstr(y, x, s.encode('utf-8'), attr)
|
||||||
|
|
||||||
# the mighty run-loop!
|
# the mighty run-loop!
|
||||||
def run(self):
|
def run(self):
|
||||||
self.done = False
|
self.done = False
|
||||||
|
@ -645,7 +648,8 @@ class Application(object):
|
||||||
|
|
||||||
# clear the error line; it might look confusing to the user
|
# clear the error line; it might look confusing to the user
|
||||||
try:
|
try:
|
||||||
self.win.addstr(self.y-1, 0, ' ' * self.x)
|
#self.win.addstr(self.y-1, 0, ' ' * self.x)
|
||||||
|
self.addstr(self.y-1, 0, ' ' * self.x)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
self.win.refresh()
|
self.win.refresh()
|
||||||
|
@ -783,7 +787,8 @@ class Application(object):
|
||||||
char = chr(junk & 255)
|
char = chr(junk & 255)
|
||||||
attr = color.build(fg, bg)
|
attr = color.build(fg, bg)
|
||||||
try:
|
try:
|
||||||
self.win.addstr(sy, sx, char, attr)
|
#self.win.addstr(sy, sx, char, attr)
|
||||||
|
self.addstr(sy, sx, char, attr)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
raise Exception, "(%d, %d, %r, %r) v. (%d, %d)" % \
|
raise Exception, "(%d, %d, %r, %r) v. (%d, %d)" % \
|
||||||
(sy, sx, fg, bg, self.y, self.x)
|
(sy, sx, fg, bg, self.y, self.x)
|
||||||
|
@ -914,8 +919,8 @@ class Application(object):
|
||||||
for j in range(0, slot.height):
|
for j in range(0, slot.height):
|
||||||
char = chr(self.win.inch(j + slot.y_offset, limit) & 255)
|
char = chr(self.win.inch(j + slot.y_offset, limit) & 255)
|
||||||
attr = color.build('default', shade, 'bold')
|
attr = color.build('default', shade, 'bold')
|
||||||
self.win.addstr(j + slot.y_offset, limit + w.mode.lmargin,
|
#self.win.addstr(j + slot.y_offset, limit + w.mode.lmargin, char, attr)
|
||||||
char, attr)
|
self.addstr(j + slot.y_offset, limit + w.mode.lmargin, char, attr)
|
||||||
|
|
||||||
def _draw_slot(self, i):
|
def _draw_slot(self, i):
|
||||||
slot = self.bufferlist.slots[i]
|
slot = self.bufferlist.slots[i]
|
||||||
|
@ -967,7 +972,8 @@ class Application(object):
|
||||||
return
|
return
|
||||||
status = slot.window.mode.get_status_bar()
|
status = slot.window.mode.get_status_bar()
|
||||||
status = status.ljust(slot.width)[:slot.width]
|
status = status.ljust(slot.width)[:slot.width]
|
||||||
self.win.addstr(slot.height + slot.y_offset, 0, status, curses.A_REVERSE)
|
#self.win.addstr(slot.height + slot.y_offset, 0, status, curses.A_REVERSE)
|
||||||
|
self.addstr(slot.height + slot.y_offset, 0, status, curses.A_REVERSE)
|
||||||
|
|
||||||
# input bar drawing
|
# input bar drawing
|
||||||
def draw_minibuffer(self):
|
def draw_minibuffer(self):
|
||||||
|
@ -978,9 +984,10 @@ class Application(object):
|
||||||
for i in range(0, len(lines)):
|
for i in range(0, len(lines)):
|
||||||
line = lines[i]
|
line = lines[i]
|
||||||
try:
|
try:
|
||||||
self.win.addstr(self.y - len(lines) + i, 0, line, attr)
|
#self.win.addstr(self.y - len(lines) + i, 0, line, attr)
|
||||||
|
self.addstr(self.y - len(lines) + i, 0, line, attr)
|
||||||
except:
|
except:
|
||||||
pass
|
raise
|
||||||
if self.error_string or not self.mini_buffer_is_open():
|
if self.error_string or not self.mini_buffer_is_open():
|
||||||
return
|
return
|
||||||
pattr = color.build('cyan', 'default', 'bold')
|
pattr = color.build('cyan', 'default', 'bold')
|
||||||
|
@ -988,7 +995,8 @@ class Application(object):
|
||||||
for i in range(0, len(plines)):
|
for i in range(0, len(plines)):
|
||||||
pline = plines[i]
|
pline = plines[i]
|
||||||
try:
|
try:
|
||||||
self.win.addstr(self.y - len(lines) + i, 0, pline, pattr)
|
#self.win.addstr(self.y - len(lines) + i, 0, pline, pattr)
|
||||||
|
self.addstr(self.y - len(lines) + i, 0, pline, pattr)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
179
method/utf8.py
179
method/utf8.py
|
@ -1,25 +1,174 @@
|
||||||
import os, commands, re, tempfile
|
import re
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
import unicodedata
|
||||||
|
|
||||||
import buffer, default, dirutil, lex, regex, util, window
|
|
||||||
from point import Point
|
|
||||||
|
|
||||||
from method import Method, Argument, arg
|
from method import Method, Argument, arg
|
||||||
|
|
||||||
class Utf8Get(Method):
|
category_map = {
|
||||||
def _execute(self, w, **vargs):
|
'Lu': 'Letter, Uppercase',
|
||||||
p = w.logical_cursor()
|
'Ll': 'Letter, Lowercase',
|
||||||
c = w.buffer.get_substring(p, p.add(1, 0))
|
'Lt': 'Letter, Titlecase',
|
||||||
w.set_error(repr(c))
|
'Lm': 'Letter, Modifier',
|
||||||
|
'Lo': 'Letter, Other',
|
||||||
|
'Mn': 'Mark, Nonspacing',
|
||||||
|
'Mc': 'Mark, Spacing Combining',
|
||||||
|
'Me': 'Mark, Enclosing',
|
||||||
|
'Nd': 'Number, Decimal Digit',
|
||||||
|
'Nl': 'Number, Letter',
|
||||||
|
'No': 'Number, Other',
|
||||||
|
'Pc': 'Punctuation, Connector',
|
||||||
|
'Pd': 'Punctuation, Dash',
|
||||||
|
'Ps': 'Punctuation, Open',
|
||||||
|
'Pe': 'Punctuation, Close',
|
||||||
|
'Pi': 'Punctuation, Initial quote (may behave like Ps or Pe depending on usage)',
|
||||||
|
'Pf': 'Punctuation, Final quote (may behave like Ps or Pe depending on usage)',
|
||||||
|
'Po': 'Punctuation, Other',
|
||||||
|
'Sm': 'Symbol, Math',
|
||||||
|
'Sc': 'Symbol, Currency',
|
||||||
|
'Sk': 'Symbol, Modifier',
|
||||||
|
'So': 'Symbol, Other',
|
||||||
|
'Zs': 'Separator, Space',
|
||||||
|
'Zl': 'Separator, Line',
|
||||||
|
'Zp': 'Separator, Paragraph',
|
||||||
|
'Cc': 'Other, Control',
|
||||||
|
'Cf': 'Other, Format',
|
||||||
|
'Cs': 'Other, Surrogate',
|
||||||
|
'Co': 'Other, Private Use',
|
||||||
|
'Cn': 'Other, Not Assigned (no characters in the file have this property)',
|
||||||
|
}
|
||||||
|
|
||||||
|
bidirect_map = {
|
||||||
|
'L': 'Left-to-Right',
|
||||||
|
'LRE': 'Left-to-Right Embedding',
|
||||||
|
'LRO': 'Left-to-Right Override',
|
||||||
|
'R': 'Right-to-Left',
|
||||||
|
'AL': 'Right-to-Left Arabic',
|
||||||
|
'RLE': 'Right-to-Left Embedding',
|
||||||
|
'RLO': 'Right-to-Left Override',
|
||||||
|
'PDF': 'Pop Directional Format',
|
||||||
|
'EN': 'European Number',
|
||||||
|
'ES': 'European Number Separator',
|
||||||
|
'ET': 'European Number Terminator',
|
||||||
|
'AN': 'Arabic Number',
|
||||||
|
'CS': 'Common Number Separator',
|
||||||
|
'NSM': 'Nonspacing Mark',
|
||||||
|
'BN': 'Boundary Neutral',
|
||||||
|
'B': 'Paragraph Separator',
|
||||||
|
'S': 'Segment Separator',
|
||||||
|
'WS': 'Whitespace',
|
||||||
|
'ON': 'Other Neutrals',
|
||||||
|
}
|
||||||
|
|
||||||
|
combine_map = {
|
||||||
|
0: 'Spacing, split, enclosing, reordrant, and Tibetan subjoined',
|
||||||
|
1: 'Overlays and interior',
|
||||||
|
7: 'Nuktas',
|
||||||
|
8: 'Hiragana/Katakana voicing marks',
|
||||||
|
9: 'Viramas',
|
||||||
|
10: 'Start of fixed position classes',
|
||||||
|
199: 'End of fixed position classes',
|
||||||
|
200: 'Below left attached',
|
||||||
|
202: 'Below attached',
|
||||||
|
204: 'Below right attached',
|
||||||
|
208: 'Left attached (reordrant around single base character)',
|
||||||
|
210: 'Right attached',
|
||||||
|
212: 'Above left attached',
|
||||||
|
214: 'Above attached',
|
||||||
|
216: 'Above right attached',
|
||||||
|
218: 'Below left',
|
||||||
|
220: 'Below',
|
||||||
|
222: 'Below right',
|
||||||
|
224: 'Left (reordrant around single base character)',
|
||||||
|
226: 'Right',
|
||||||
|
228: 'Above right',
|
||||||
|
230: 'Above',
|
||||||
|
232: 'Above left',
|
||||||
|
233: 'Double below',
|
||||||
|
234: 'Double above',
|
||||||
|
240: 'Below (iota subscript)',
|
||||||
|
}
|
||||||
|
|
||||||
|
width_map = {
|
||||||
|
'W': 'East Asian Wide',
|
||||||
|
'F': 'East Asian Full-width',
|
||||||
|
'A': 'East Asian Ambiguous',
|
||||||
|
'H': 'East Asian Half-width',
|
||||||
|
'Na': 'East Asian Narrow',
|
||||||
|
'N': 'Narrow',
|
||||||
|
}
|
||||||
|
|
||||||
|
def unicodeget(u, fname, fallback):
|
||||||
|
try:
|
||||||
|
f = getattr(unicodedata, fname)
|
||||||
|
value = f(u)
|
||||||
|
if value:
|
||||||
|
return value
|
||||||
|
except:
|
||||||
|
return fallback
|
||||||
|
|
||||||
class Utf8Describe(Method):
|
class Utf8Describe(Method):
|
||||||
|
'''get detailed utf-8 data about a particular utf-8 code point'''
|
||||||
|
args = [arg("code", t=type(""), p="Code Point: ", h="UTF-8 code point to use")]
|
||||||
|
cpt_re = re.compile('^\\u(?:[0-9a-fA-F]{2})+$')
|
||||||
|
format = '''
|
||||||
|
Glyph %s
|
||||||
|
Name %s
|
||||||
|
Category %s
|
||||||
|
|
||||||
|
Bidirectional %s
|
||||||
|
Combining %s
|
||||||
|
Width %s
|
||||||
|
Mirroring %s
|
||||||
|
Decomposition %s
|
||||||
|
|
||||||
|
Decimal %s
|
||||||
|
Digit %s
|
||||||
|
Lookup %s
|
||||||
|
Normalize %s
|
||||||
|
Numeric %s'''
|
||||||
def _execute(self, w, **vargs):
|
def _execute(self, w, **vargs):
|
||||||
w.set_error("not implemented")
|
s = "u'" + vargs['code'] + "'"
|
||||||
|
try:
|
||||||
|
u = eval(s, {}, {})
|
||||||
|
w.insert_string_at_cursor(u)
|
||||||
|
except:
|
||||||
|
w.set_error("invalid: %s" % vargs['data'])
|
||||||
|
return
|
||||||
|
|
||||||
|
a = unicodeget(u, 'category', '??')
|
||||||
|
b = unicodeget(u, 'bidirectional', '?')
|
||||||
|
c = unicodeget(u, 'combining', '?')
|
||||||
|
d = unicodeget(u, 'east_asian_width', '?')
|
||||||
|
|
||||||
|
name = unicodeget(u, 'name', 'Unnamed')
|
||||||
|
category = category_map.get(a, 'No Category') + ' (%s)' % a
|
||||||
|
bidirect = bidirect_map.get(b, 'No Directional Info') + ' (%s)' % b
|
||||||
|
combine = combine_map.get(c, 'No Combining Info') + ' (%s)' % c
|
||||||
|
|
||||||
|
mirror = unicodeget(u, 'mirrored', 'Unknown Mirroring')
|
||||||
|
width = width_map.get(d, 'Unknown Width') + ' (%s)' % d
|
||||||
|
|
||||||
|
decomposition = unicodeget(u, 'decomposition', 'No Decomposition Info')
|
||||||
|
decimal = unicodeget(u, 'decimal', 'n/a')
|
||||||
|
digit = unicodeget(u, 'digit', 'n/a')
|
||||||
|
lookup = unicodeget(u, 'lookup', 'n/a')
|
||||||
|
normalize = unicodeget(u, 'normalize', 'n/a')
|
||||||
|
numeric = unicodeget(u, 'numeric', 'n/a')
|
||||||
|
|
||||||
|
data = self.format % (u, name, category, bidirect, combine, width,
|
||||||
|
mirror, decomposition, decimal, digit, lookup,
|
||||||
|
normalize, numeric)
|
||||||
|
w.application.data_buffer('*Utf8-Info*', data.strip(), switch_to=True)
|
||||||
|
|
||||||
|
class Utf8DescribeChar(Utf8Describe):
|
||||||
|
'''get utf-8 representation of the highlighted character'''
|
||||||
|
args = []
|
||||||
|
def _execute(self, w, **vargs):
|
||||||
|
p = w.logical_cursor()
|
||||||
|
u = w.buffer.get_substring(p, p.add(1, 0))
|
||||||
|
Utf8Describe._execute(self, w, code=u)
|
||||||
|
|
||||||
class Utf8Insert(Method):
|
class Utf8Insert(Method):
|
||||||
'''insert the specified UTF-8 character into the buffer'''
|
'''insert UTF-8 data into the buffer'''
|
||||||
args = [arg("data", t=type(""), p="Data: ",
|
args = [arg("data", t=type(""), p="UTF-8 Data: ", h="the UTF-8 data to use")]
|
||||||
h="the UTF-8 escaped data to use to use")]
|
|
||||||
def _execute(self, w, **vargs):
|
def _execute(self, w, **vargs):
|
||||||
s = "u'" + vargs['data'] + "'"
|
s = "u'" + vargs['data'] + "'"
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in New Issue