m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

800 lines
24 KiB

6 months ago
  1. # -*- coding: utf-8 -*-
  2. #*****************************************************************************
  3. # Copyright (C) 2006 Jorgen Stenarson. <jorgen.stenarson@bostream.nu>
  4. #
  5. # Distributed under the terms of the BSD License. The full license is in
  6. # the file COPYING, distributed as part of this software.
  7. #*****************************************************************************
  8. from __future__ import print_function, unicode_literals, absolute_import
  9. import re, operator, sys
  10. from . import wordmatcher
  11. import pyreadline.clipboard as clipboard
  12. from pyreadline.logger import log
  13. from pyreadline.unicode_helper import ensure_unicode, biter
  14. kill_ring_to_clipboard = False #set to true to copy every addition to kill ring to clipboard
  15. class NotAWordError(IndexError):
  16. pass
  17. def quote_char(c):
  18. if ord(c) > 0:
  19. return c
  20. ############## Line positioner ########################
  21. class LinePositioner(object):
  22. def __call__(self, line):
  23. NotImplementedError("Base class !!!")
  24. class NextChar(LinePositioner):
  25. def __call__(self, line):
  26. if line.point < len(line.line_buffer):
  27. return line.point + 1
  28. else:
  29. return line.point
  30. NextChar = NextChar()
  31. class PrevChar(LinePositioner):
  32. def __call__(self, line):
  33. if line.point > 0:
  34. return line.point - 1
  35. else:
  36. return line.point
  37. PrevChar = PrevChar()
  38. class NextWordStart(LinePositioner):
  39. def __call__(self, line):
  40. return line.next_start_segment(line.line_buffer, line.is_word_token)[line.point]
  41. NextWordStart = NextWordStart()
  42. class NextWordEnd(LinePositioner):
  43. def __call__(self, line):
  44. return line.next_end_segment(line.line_buffer, line.is_word_token)[line.point]
  45. NextWordEnd = NextWordEnd()
  46. class PrevWordStart(LinePositioner):
  47. def __call__(self, line):
  48. return line.prev_start_segment(line.line_buffer, line.is_word_token)[line.point]
  49. PrevWordStart = PrevWordStart()
  50. class WordStart(LinePositioner):
  51. def __call__(self, line):
  52. if line.is_word_token(line.get_line_text()[Point(line):Point(line) + 1]):
  53. if Point(line) > 0 and line.is_word_token(line.get_line_text()[Point(line) - 1:Point(line)]):
  54. return PrevWordStart(line)
  55. else:
  56. return line.point
  57. else:
  58. raise NotAWordError("Point is not in a word")
  59. WordStart = WordStart()
  60. class WordEnd(LinePositioner):
  61. def __call__(self, line):
  62. if line.is_word_token(line.get_line_text()[Point(line):Point(line) + 1]):
  63. if line.is_word_token(line.get_line_text()[Point(line) + 1:Point(line) + 2]):
  64. return NextWordEnd(line)
  65. else:
  66. return line.point
  67. else:
  68. raise NotAWordError("Point is not in a word")
  69. WordEnd = WordEnd()
  70. class PrevWordEnd(LinePositioner):
  71. def __call__(self, line):
  72. return line.prev_end_segment(line.line_buffer, line.is_word_token)[line.point]
  73. PrevWordEnd = PrevWordEnd()
  74. class PrevSpace(LinePositioner):
  75. def __call__(self, line):
  76. point = line.point
  77. if line[point - 1:point].get_line_text() == " ":
  78. while point > 0 and line[point - 1:point].get_line_text() == " ":
  79. point -= 1
  80. while point > 0 and line[point - 1:point].get_line_text() != " ":
  81. point -= 1
  82. return point
  83. PrevSpace = PrevSpace()
  84. class StartOfLine(LinePositioner):
  85. def __call__(self, line):
  86. return 0
  87. StartOfLine = StartOfLine()
  88. class EndOfLine(LinePositioner):
  89. def __call__(self, line):
  90. return len(line.line_buffer)
  91. EndOfLine = EndOfLine()
  92. class Point(LinePositioner):
  93. def __call__(self, line):
  94. return line.point
  95. Point = Point()
  96. class Mark(LinePositioner):
  97. def __call__(self, line):
  98. return line.mark
  99. k = Mark()
  100. all_positioners = [(value.__class__.__name__, value)
  101. for key, value in globals().items()
  102. if isinstance(value, LinePositioner)]
  103. all_positioners.sort()
  104. ############### LineSlice #################
  105. class LineSlice(object):
  106. def __call__(self, line):
  107. NotImplementedError("Base class !!!")
  108. class CurrentWord(LineSlice):
  109. def __call__(self, line):
  110. return slice(WordStart(line), WordEnd(line), None)
  111. CurrentWord = CurrentWord()
  112. class NextWord(LineSlice):
  113. def __call__(self, line):
  114. work = TextLine(line)
  115. work.point = NextWordStart
  116. start = work.point
  117. stop = NextWordEnd(work)
  118. return slice(start, stop)
  119. NextWord = NextWord()
  120. class PrevWord(LineSlice):
  121. def __call__(self, line):
  122. work = TextLine(line)
  123. work.point = PrevWordEnd
  124. stop = work.point
  125. start = PrevWordStart(work)
  126. return slice(start, stop)
  127. PrevWord = PrevWord()
  128. class PointSlice(LineSlice):
  129. def __call__(self, line):
  130. return slice(Point(line), Point(line) + 1, None)
  131. PointSlice = PointSlice()
  132. ############### TextLine ######################
  133. class TextLine(object):
  134. def __init__(self, txtstr, point = None, mark = None):
  135. self.line_buffer = []
  136. self._point = 0
  137. self.mark = -1
  138. self.undo_stack = []
  139. self.overwrite = False
  140. if isinstance(txtstr, TextLine): #copy
  141. self.line_buffer = txtstr.line_buffer[:]
  142. if point is None:
  143. self.point = txtstr.point
  144. else:
  145. self.point = point
  146. if mark is None:
  147. self.mark = txtstr.mark
  148. else:
  149. self.mark = mark
  150. else:
  151. self._insert_text(txtstr)
  152. if point is None:
  153. self.point = 0
  154. else:
  155. self.point = point
  156. if mark is None:
  157. self.mark = -1
  158. else:
  159. self.mark = mark
  160. self.is_word_token = wordmatcher.is_word_token
  161. self.next_start_segment = wordmatcher.next_start_segment
  162. self.next_end_segment = wordmatcher.next_end_segment
  163. self.prev_start_segment = wordmatcher.prev_start_segment
  164. self.prev_end_segment = wordmatcher.prev_end_segment
  165. def push_undo(self):
  166. ltext = self.get_line_text()
  167. if self.undo_stack and ltext == self.undo_stack[-1].get_line_text():
  168. self.undo_stack[-1].point = self.point
  169. else:
  170. self.undo_stack.append(self.copy())
  171. def pop_undo(self):
  172. if len(self.undo_stack) >= 2:
  173. self.undo_stack.pop()
  174. self.set_top_undo()
  175. self.undo_stack.pop()
  176. else:
  177. self.reset_line()
  178. self.undo_stack = []
  179. def set_top_undo(self):
  180. if self.undo_stack:
  181. undo = self.undo_stack[-1]
  182. self.line_buffer = undo.line_buffer
  183. self.point = undo.point
  184. self.mark = undo.mark
  185. else:
  186. pass
  187. def __repr__(self):
  188. return 'TextLine("%s",point=%s,mark=%s)'%(self.line_buffer, self.point, self.mark)
  189. def copy(self):
  190. return self.__class__(self)
  191. def set_point(self,value):
  192. if isinstance(value, LinePositioner):
  193. value = value(self)
  194. assert (value <= len(self.line_buffer))
  195. if value > len(self.line_buffer):
  196. value = len(self.line_buffer)
  197. self._point = value
  198. def get_point(self):
  199. return self._point
  200. point = property(get_point, set_point)
  201. def visible_line_width(self, position = Point):
  202. """Return the visible width of the text in line buffer up to position."""
  203. extra_char_width = len([ None for c in self[:position].line_buffer if 0x2013 <= ord(c) <= 0xFFFD])
  204. return len(self[:position].quoted_text()) + self[:position].line_buffer.count("\t")*7 + extra_char_width
  205. def quoted_text(self):
  206. quoted = [ quote_char(c) for c in self.line_buffer ]
  207. self.line_char_width = [ len(c) for c in quoted ]
  208. return ''.join(map(ensure_unicode, quoted))
  209. def get_line_text(self):
  210. buf = self.line_buffer
  211. buf = list(map(ensure_unicode, buf))
  212. return ''.join(buf)
  213. def set_line(self, text, cursor = None):
  214. self.line_buffer = [ c for c in str(text) ]
  215. if cursor is None:
  216. self.point = len(self.line_buffer)
  217. else:
  218. self.point = cursor
  219. def reset_line(self):
  220. self.line_buffer = []
  221. self.point = 0
  222. def end_of_line(self):
  223. self.point = len(self.line_buffer)
  224. def _insert_text(self, text, argument=1):
  225. text = text * argument
  226. if self.overwrite:
  227. for c in biter(text):
  228. #if self.point:
  229. self.line_buffer[self.point] = c
  230. self.point += 1
  231. else:
  232. for c in biter(text):
  233. self.line_buffer.insert(self.point, c)
  234. self.point += 1
  235. def __getitem__(self, key):
  236. #Check if key is LineSlice, convert to regular slice
  237. #and continue processing
  238. if isinstance(key, LineSlice):
  239. key = key(self)
  240. if isinstance(key, slice):
  241. if key.step is None:
  242. pass
  243. else:
  244. raise Error
  245. if key.start is None:
  246. start = StartOfLine(self)
  247. elif isinstance(key.start,LinePositioner):
  248. start = key.start(self)
  249. else:
  250. start = key.start
  251. if key.stop is None:
  252. stop = EndOfLine(self)
  253. elif isinstance(key.stop, LinePositioner):
  254. stop = key.stop(self)
  255. else:
  256. stop = key.stop
  257. return self.__class__(self.line_buffer[start:stop], point=0)
  258. elif isinstance(key, LinePositioner):
  259. return self.line_buffer[key(self)]
  260. elif isinstance(key, tuple):
  261. raise IndexError("Cannot use step in line buffer indexing") #Multiple slice not allowed
  262. else:
  263. # return TextLine(self.line_buffer[key])
  264. return self.line_buffer[key]
  265. def __delitem__(self, key):
  266. point = self.point
  267. if isinstance(key, LineSlice):
  268. key = key(self)
  269. if isinstance(key, slice):
  270. start = key.start
  271. stop = key.stop
  272. if isinstance(start, LinePositioner):
  273. start = start(self)
  274. elif start is None:
  275. start=0
  276. if isinstance(stop, LinePositioner):
  277. stop = stop(self)
  278. elif stop is None:
  279. stop = EndOfLine(self)
  280. elif isinstance(key, LinePositioner):
  281. start = key(self)
  282. stop = start + 1
  283. else:
  284. start = key
  285. stop = key + 1
  286. prev = self.line_buffer[:start]
  287. rest = self.line_buffer[stop:]
  288. self.line_buffer = prev + rest
  289. if point > stop:
  290. self.point = point - (stop - start)
  291. elif point >= start and point <= stop:
  292. self.point = start
  293. def __setitem__(self, key, value):
  294. if isinstance(key, LineSlice):
  295. key = key(self)
  296. if isinstance(key, slice):
  297. start = key.start
  298. stop = key.stop
  299. elif isinstance(key, LinePositioner):
  300. start = key(self)
  301. stop = start + 1
  302. else:
  303. start = key
  304. stop = key + 1
  305. prev = self.line_buffer[:start]
  306. value = self.__class__(value).line_buffer
  307. rest = self.line_buffer[stop:]
  308. out = prev + value + rest
  309. if len(out) >= len(self):
  310. self.point = len(self)
  311. self.line_buffer = out
  312. def __len__(self):
  313. return len(self.line_buffer)
  314. def upper(self):
  315. self.line_buffer = [x.upper() for x in self.line_buffer]
  316. return self
  317. def lower(self):
  318. self.line_buffer = [x.lower() for x in self.line_buffer]
  319. return self
  320. def capitalize(self):
  321. self.set_line(self.get_line_text().capitalize(), self.point)
  322. return self
  323. def startswith(self, txt):
  324. return self.get_line_text().startswith(txt)
  325. def endswith(self, txt):
  326. return self.get_line_text().endswith(txt)
  327. def __contains__(self, txt):
  328. return txt in self.get_line_text()
  329. lines = [TextLine("abc"),
  330. TextLine("abc def"),
  331. TextLine("abc def ghi"),
  332. TextLine(" abc def "),
  333. ]
  334. l = lines[2]
  335. l.point = 5
  336. class ReadLineTextBuffer(TextLine):
  337. def __init__(self,txtstr, point = None, mark = None):
  338. super(ReadLineTextBuffer, self).__init__(txtstr, point, mark)
  339. self.enable_win32_clipboard = True
  340. self.selection_mark = -1
  341. self.enable_selection = True
  342. self.kill_ring = []
  343. def __repr__(self):
  344. return 'ReadLineTextBuffer'\
  345. '("%s",point=%s,mark=%s,selection_mark=%s)'%\
  346. (self.line_buffer, self.point, self.mark,self.selection_mark)
  347. def insert_text(self, char, argument=1):
  348. self.delete_selection()
  349. self.selection_mark = -1
  350. self._insert_text(char, argument)
  351. def to_clipboard(self):
  352. if self.enable_win32_clipboard:
  353. clipboard.set_clipboard_text(self.get_line_text())
  354. ######### Movement
  355. def beginning_of_line(self):
  356. self.selection_mark = -1
  357. self.point = StartOfLine
  358. def end_of_line(self):
  359. self.selection_mark = -1
  360. self.point = EndOfLine
  361. def forward_char(self,argument = 1):
  362. if argument < 0:
  363. self.backward_char(-argument)
  364. self.selection_mark = -1
  365. for x in range(argument):
  366. self.point = NextChar
  367. def backward_char(self, argument=1):
  368. if argument < 0:
  369. self.forward_char(-argument)
  370. self.selection_mark = -1
  371. for x in range(argument):
  372. self.point = PrevChar
  373. def forward_word(self,argument=1):
  374. if argument<0:
  375. self.backward_word(-argument)
  376. self.selection_mark=-1
  377. for x in range(argument):
  378. self.point = NextWordStart
  379. def backward_word(self, argument=1):
  380. if argument < 0:
  381. self.forward_word(-argument)
  382. self.selection_mark = -1
  383. for x in range(argument):
  384. self.point = PrevWordStart
  385. def forward_word_end(self, argument=1):
  386. if argument < 0:
  387. self.backward_word_end(-argument)
  388. self.selection_mark = -1
  389. for x in range(argument):
  390. self.point = NextWordEnd
  391. def backward_word_end(self, argument=1):
  392. if argument < 0:
  393. self.forward_word_end(-argument)
  394. self.selection_mark = -1
  395. for x in range(argument):
  396. self.point = NextWordEnd
  397. ######### Movement select
  398. def beginning_of_line_extend_selection(self):
  399. if self.enable_selection and self.selection_mark < 0:
  400. self.selection_mark = self.point
  401. self.point = StartOfLine
  402. def end_of_line_extend_selection(self):
  403. if self.enable_selection and self.selection_mark < 0:
  404. self.selection_mark = self.point
  405. self.point = EndOfLine
  406. def forward_char_extend_selection(self,argument=1):
  407. if argument < 0:
  408. self.backward_char_extend_selection(-argument)
  409. if self.enable_selection and self.selection_mark < 0:
  410. self.selection_mark = self.point
  411. for x in range(argument):
  412. self.point = NextChar
  413. def backward_char_extend_selection(self, argument=1):
  414. if argument < 0:
  415. self.forward_char_extend_selection(-argument)
  416. if self.enable_selection and self.selection_mark < 0:
  417. self.selection_mark = self.point
  418. for x in range(argument):
  419. self.point = PrevChar
  420. def forward_word_extend_selection(self, argument=1):
  421. if argument < 0:
  422. self.backward_word_extend_selection(-argument)
  423. if self.enable_selection and self.selection_mark < 0:
  424. self.selection_mark = self.point
  425. for x in range(argument):
  426. self.point = NextWordStart
  427. def backward_word_extend_selection(self, argument=1):
  428. if argument < 0:
  429. self.forward_word_extend_selection(-argument)
  430. if self.enable_selection and self.selection_mark < 0:
  431. self.selection_mark = self.point
  432. for x in range(argument):
  433. self.point = PrevWordStart
  434. def forward_word_end_extend_selection(self, argument=1):
  435. if argument < 0:
  436. self.backward_word_end_extend_selection(-argument)
  437. if self.enable_selection and self.selection_mark < 0:
  438. self.selection_mark = self.point
  439. for x in range(argument):
  440. self.point = NextWordEnd
  441. def backward_word_end_extend_selection(self, argument=1):
  442. if argument < 0:
  443. self.forward_word_end_extend_selection(-argument)
  444. if self.enable_selection and self.selection_mark < 0:
  445. self.selection_mark = self.point
  446. for x in range(argument):
  447. self.point = PrevWordEnd
  448. ######### delete
  449. def delete_selection(self):
  450. if self.enable_selection and self.selection_mark >= 0:
  451. if self.selection_mark < self.point:
  452. del self[self.selection_mark:self.point]
  453. self.selection_mark = -1
  454. else:
  455. del self[self.point:self.selection_mark]
  456. self.selection_mark = -1
  457. return True
  458. else:
  459. self.selection_mark = -1
  460. return False
  461. def delete_char(self, argument=1):
  462. if argument < 0:
  463. self.backward_delete_char(-argument)
  464. if self.delete_selection():
  465. argument -= 1
  466. for x in range(argument):
  467. del self[Point]
  468. def backward_delete_char(self, argument=1):
  469. if argument < 0:
  470. self.delete_char(-argument)
  471. if self.delete_selection():
  472. argument -= 1
  473. for x in range(argument):
  474. if self.point > 0:
  475. self.backward_char()
  476. self.delete_char()
  477. def forward_delete_word(self, argument=1):
  478. if argument < 0:
  479. self.backward_delete_word(-argument)
  480. if self.delete_selection():
  481. argument -= 1
  482. for x in range(argument):
  483. del self[Point:NextWordStart]
  484. def backward_delete_word(self, argument=1):
  485. if argument < 0:
  486. self.forward_delete_word(-argument)
  487. if self.delete_selection():
  488. argument -= 1
  489. for x in range(argument):
  490. del self[PrevWordStart:Point]
  491. def delete_current_word(self):
  492. if not self.delete_selection():
  493. del self[CurrentWord]
  494. self.selection_mark =- 1
  495. def delete_horizontal_space(self):
  496. if self[Point] in " \t":
  497. del self[PrevWordEnd:NextWordStart]
  498. self.selection_mark = -1
  499. ######### Case
  500. def upcase_word(self):
  501. p = self.point
  502. try:
  503. self[CurrentWord] = self[CurrentWord].upper()
  504. self.point = p
  505. except NotAWordError:
  506. pass
  507. def downcase_word(self):
  508. p = self.point
  509. try:
  510. self[CurrentWord] = self[CurrentWord].lower()
  511. self.point = p
  512. except NotAWordError:
  513. pass
  514. def capitalize_word(self):
  515. p = self.point
  516. try:
  517. self[CurrentWord] = self[CurrentWord].capitalize()
  518. self.point = p
  519. except NotAWordError:
  520. pass
  521. ########### Transpose
  522. def transpose_chars(self):
  523. p2 = Point(self)
  524. if p2 == 0:
  525. return
  526. elif p2 == len(self):
  527. p2 = p2 - 1
  528. p1 = p2 - 1
  529. self[p2], self[p1] = self[p1], self[p2]
  530. self.point = p2 + 1
  531. def transpose_words(self):
  532. word1 = TextLine(self)
  533. word2 = TextLine(self)
  534. if self.point == len(self):
  535. word2.point = PrevWordStart
  536. word1.point = PrevWordStart(word2)
  537. else:
  538. word1.point = PrevWordStart
  539. word2.point = NextWordStart
  540. stop1 = NextWordEnd(word1)
  541. stop2 = NextWordEnd(word2)
  542. start1 = word1.point
  543. start2 = word2.point
  544. self[start2:stop2] = word1[Point:NextWordEnd]
  545. self[start1:stop1] = word2[Point:NextWordEnd]
  546. self.point = stop2
  547. ############ Kill
  548. def kill_line(self):
  549. self.add_to_kill_ring(self[self.point:])
  550. del self.line_buffer[self.point:]
  551. def kill_whole_line(self):
  552. self.add_to_kill_ring(self[:])
  553. del self[:]
  554. def backward_kill_line(self):
  555. del self[StartOfLine:Point]
  556. def unix_line_discard(self):
  557. del self[StartOfLine:Point]
  558. pass
  559. def kill_word(self):
  560. """Kills to next word ending"""
  561. del self[Point:NextWordEnd]
  562. def backward_kill_word(self):
  563. """Kills to next word ending"""
  564. if not self.delete_selection():
  565. del self[PrevWordStart:Point]
  566. self.selection_mark = -1
  567. def forward_kill_word(self):
  568. """Kills to next word ending"""
  569. if not self.delete_selection():
  570. del self[Point:NextWordEnd]
  571. self.selection_mark = -1
  572. def unix_word_rubout(self):
  573. if not self.delete_selection():
  574. del self[PrevSpace:Point]
  575. self.selection_mark = -1
  576. def kill_region(self):
  577. pass
  578. def copy_region_as_kill(self):
  579. pass
  580. def copy_backward_word(self):
  581. pass
  582. def copy_forward_word(self):
  583. pass
  584. def yank(self):
  585. self.paste_from_kill_ring()
  586. def yank_pop(self):
  587. pass
  588. ############## Mark
  589. def set_mark(self):
  590. self.mark = self.point
  591. def exchange_point_and_mark(self):
  592. pass
  593. def copy_region_to_clipboard(self): # ()
  594. '''Copy the text in the region to the windows clipboard.'''
  595. if self.enable_win32_clipboard:
  596. mark = min(self.mark, len(self.line_buffer))
  597. cursor = min(self.point, len(self.line_buffer))
  598. if self.mark == -1:
  599. return
  600. begin = min(cursor, mark)
  601. end = max(cursor, mark)
  602. toclipboard = "".join(self.line_buffer[begin:end])
  603. clipboard.SetClipboardText(toclipboard)
  604. def copy_selection_to_clipboard(self): # ()
  605. '''Copy the text in the region to the windows clipboard.'''
  606. if self.enable_win32_clipboard and self.enable_selection and self.selection_mark >= 0:
  607. selection_mark = min(self.selection_mark,len(self.line_buffer))
  608. cursor = min(self.point,len(self.line_buffer))
  609. if self.selection_mark == -1:
  610. return
  611. begin = min(cursor, selection_mark)
  612. end = max(cursor, selection_mark)
  613. toclipboard = "".join(self.line_buffer[begin:end])
  614. clipboard.SetClipboardText(toclipboard)
  615. def cut_selection_to_clipboard(self): # ()
  616. self.copy_selection_to_clipboard()
  617. self.delete_selection()
  618. ############## Paste
  619. ############## Kill ring
  620. def add_to_kill_ring(self,txt):
  621. self.kill_ring = [txt]
  622. if kill_ring_to_clipboard:
  623. clipboard.SetClipboardText(txt.get_line_text())
  624. def paste_from_kill_ring(self):
  625. if self.kill_ring:
  626. self.insert_text(self.kill_ring[0])
  627. ##################################################################
  628. q = ReadLineTextBuffer("asff asFArw ewrWErhg", point=8)
  629. q = TextLine("asff asFArw ewrWErhg", point=8)
  630. def show_pos(buff, pos, chr = "."):
  631. l = len(buff.line_buffer)
  632. def choice(bool):
  633. if bool:
  634. return chr
  635. else:
  636. return " "
  637. return "".join([choice(pos==idx) for idx in range(l + 1)])
  638. def test_positioner(buff, points, positioner):
  639. print((" %s "%positioner.__class__.__name__).center(40, "-"))
  640. buffstr = buff.line_buffer
  641. print('"%s"'%(buffstr))
  642. for point in points:
  643. b = TextLine(buff, point = point)
  644. out=[" "] * (len(buffstr) + 1)
  645. pos = positioner(b)
  646. if pos == point:
  647. out[pos] = "&"
  648. else:
  649. out[point] = "."
  650. out[pos] = "^"
  651. print('"%s"'%("".join(out)))
  652. if __name__ == "__main__":
  653. print('%-15s "%s"'%("Position", q.get_line_text()))
  654. print('%-15s "%s"'%("Point", show_pos(q, q.point)))
  655. for name, positioner in all_positioners:
  656. pos = positioner(q)
  657. []
  658. print('%-15s "%s"'%(name, show_pos(q, pos, "^")))
  659. l = ReadLineTextBuffer("kjjk asads asad")
  660. l.point = EndOfLine