anchor.diff:      ((string= (uiop:getenv "MSYSCON") "mintty.exe") :mintty)
       ((uiop:getenv "ConEmuBuild") :conemu)
       (t :cmd.exe)))
  +
  +;; windows terminal setting
  +(defclass windows-term-setting ()
  +  ((disp-char-width ;; character width setting for display
  +                    ;;   t        : use default function
  +                    ;;   nil      : no conversion
  +                    ;;   function : use custom function
  +                    ;;                (lambda (code) width)
  +    :initform nil
  +    :initarg :disp-char-width)
  +   (pos-char-width  ;; character width setting for position
  +                    ;;   t        : use default function
  +                    ;;   nil      : no conversion
  +                    ;;   function : use custom function
  +                    ;;                (lambda (code) width)
  +    :initform nil
  +    :initarg :pos-char-width)
  +   (cur-char-width  ;; character width setting for cursor movement
  +                    ;;   t        : use default function
  +                    ;;   nil      : no conversion
  +                    ;;   function : use custom function
  +                    ;;                (lambda (code) width)
  +    :initform nil
  +    :initarg :cur-char-width)
  +   ))
  +(defvar *windows-term-setting*
  +  (case *windows-term-type*
  +    (:mintty
  +     (make-instance 'windows-term-setting
  +                    :disp-char-width t
  +                    :pos-char-width  t
  +                    :cur-char-width  t))
  +    (:conemu
  +     (make-instance 'windows-term-setting
  +                    :disp-char-width t
  +                    :pos-char-width  t
  +                    :cur-char-width  nil))
  +    (t
  +     (make-instance 'windows-term-setting
  +                    :disp-char-width nil
  +                    :pos-char-width  nil
  +                    :cur-char-width  nil))))
  +(defun disp-char-width-func ()
  +  (let ((fn (slot-value *windows-term-setting* 'disp-char-width)))
  +    (if (functionp fn)
  +        (lambda (code)
  +          ;; check zero-width-space character (#\u200b)
  +          (if (= code #x200b)
  +              0
  +              (funcall fn code)))
  +        (lambda (code)
  +          ;; check zero-width-space character (#\u200b)
  +          (if (= code #x200b)
  +              0
  +              (if (lem-base:wide-char-p (code-char code)) 2 1))))))
  +(defun pos-char-width-func ()
  +  (let ((fn (slot-value *windows-term-setting* 'pos-char-width)))
  +    (if (functionp fn)
  +        fn
  +        (lambda (code)
  +          ;; check utf-16 surrogate pair characters
  +          (if (< code #x10000) 1 2)))))
  +(defun cur-char-width-func ()
  +  (let ((fn (slot-value *windows-term-setting* 'cur-char-width)))
  +    (if (functionp fn)
  +        (lambda (code)
  +          ;; check zero-width-space character (#\u200b)
  +          (if (= code #x200b)
  +              0
  +              (funcall fn code)))
  +        (lambda (code)
  +          ;; check zero-width-space character (#\u200b)
  +          (if (= code #x200b)
  +              0
  +              (if (lem-base:wide-char-p (code-char code)) 2 1))))))
   
   ;; load windows dll
   ;;  (we load winmm.dll with a full path because it isn't listed in
  
positive.code:                                    (mouse-get-disp-x (lem:window-view window) x y)))
  (defun mouse-event-proc (bstate x1 y1)
    (lambda ()
      (cond
        ;; button1 down
        ((logtest bstate (logior charms/ll:BUTTON1_PRESSED
  
negative.code:          (pos-y    (get-pos-y view x y :modeline modeline)))
      (loop :while (< disp-x disp-x0)
         :for code := (get-charcode-from-scrwin view pos-x pos-y)
         :do (incf disp-x (funcall disp-char-width-fn code))
             (incf pos-x  (funcall pos-char-width-fn  code)))
      pos-x))
  (defun get-pos-y (view x y &key (modeline nil))
    (+ y (ncurses-view-y view) (if modeline (ncurses-view-height view) 0)))
  
  ;; for mintty
  ;; get cur-x for moving cursor position properly
  (defun get-cur-x (view x y &key (modeline nil))
    (unless (slot-value *windows-term-setting* 'cur-char-width)
      (return-from get-cur-x (get-pos-x view x y :modeline modeline)))
    (let* ((disp-char-width-fn (disp-char-width-func))
           (pos-char-width-fn  (pos-char-width-func))
           (cur-char-width-fn  (cur-char-width-func))
           (start-x (ncurses-view-x view))
           (disp-x0 (+ x start-x))
           (disp-x  0)
           (pos-x   0)
           (pos-y   (get-pos-y view x y :modeline modeline))
           (cur-x   0))
      (loop :while (< disp-x disp-x0)
         :for code := (get-charcode-from-scrwin view pos-x pos-y)
         :do (incf disp-x (funcall disp-char-width-fn code))
             (incf pos-x  (funcall pos-char-width-fn  code))
             (incf cur-x  (funcall cur-char-width-fn  code)))
      cur-x))
  
  ;; for mintty and ConEmu
  ;; adjust line width by using zero-width-space character (#\u200b)
  (defun adjust-line (view x y &key (modeline nil))
    (unless (slot-value *windows-term-setting* 'pos-char-width)
      (return-from adjust-line))
    (let* ((start-x    (ncurses-view-x view))
           (disp-width (ncurses-view-width view))
  