Skip to content

cursor behavior for full/ambiguous width characters #9

@buganini

Description

@buganini

Currently I'm using following hack in my program:

--- a/pyte/screens.py
+++ b/pyte/screens.py
@@ -28,6 +28,7 @@ from __future__ import (
     absolute_import, unicode_literals, division
 )

+import bsdconv
 import copy
 import math
 import operator
@@ -36,6 +37,7 @@ from itertools import islice, repeat

 from . import modes as mo, graphics as g, charsets as cs

+width_counter=bsdconv.Bsdconv("utf-8:width:null")

 try:
     xrange
@@ -392,6 +394,10 @@ class Screen(list):
         char = char.translate([self.g0_charset,
                                self.g1_charset][self.charset])

+       width_counter.conv(char.encode("utf-8"))
+       width_info=width_counter.info()
+       width=width_info['full']*2+width_info['ambi']*2+width_info['half']
+
         # If this was the last column in a line and auto wrap mode is
         # enabled, move the cursor to the next line. Otherwise replace
         # characters already displayed with newly entered.
@@ -410,9 +416,13 @@ class Screen(list):
         self[self.cursor.y][self.cursor.x] = self.cursor.attrs \
             ._replace(data=char)

+       if width>1:
+               self[self.cursor.y][self.cursor.x+1] = self.cursor.attrs \
+                   ._replace(data="")
+
         # .. note:: We can't use :meth:`cursor_forward()`, because that
         #           way, we'll never know when to linefeed.
-        self.cursor.x += 1
+        self.cursor.x += width

     def carriage_return(self):
         """Move the cursor to the beginning of the current line."""

there should be a similar but cleaner way to determine character width, and especially, there is a set of "east-asian ambiguous width" characters, its width depends on locale, I treat it as fullwidth (*2) in my case.

http://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt
https://github.com/buganini/bsdconv/blob/master/codecs/inter/WIDTH.c

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions