|
6 | 6 | :skk-preedit |
7 | 7 | :skk-henkan-mode-p |
8 | 8 | :skk-henkan-key |
| 9 | + :skk-henkan-start |
9 | 10 | :skk-okurigana-consonant |
10 | 11 | :skk-okurigana-kana |
11 | 12 | :skk-candidates |
|
36 | 37 | (defvar *default-cursor-color* nil |
37 | 38 | "Saved default cursor color to restore when SKK is disabled.") |
38 | 39 |
|
| 40 | +;;; Preedit display configuration |
| 41 | +(defparameter *skk-preedit-display-style* :floating-window |
| 42 | + "Style for SKK preedit display. |
| 43 | +:floating-window - Display at cursor position using floating-window (default) |
| 44 | +:echo-area - Display in echo area (legacy behavior)") |
| 45 | + |
| 46 | +(defparameter *skk-preedit-background-color* nil |
| 47 | + "Background color for floating-window preedit display. |
| 48 | +NIL means use transparent/default buffer background.") |
| 49 | + |
| 50 | +(defparameter *skk-preedit-offset-y* 0 |
| 51 | + "Vertical offset for preedit window from cursor position. |
| 52 | +Negative values move the window up, positive values move it down.") |
| 53 | + |
| 54 | +;;; Preedit window state |
| 55 | +(defvar *skk-preedit-window* nil |
| 56 | + "Current SKK preedit floating window, or NIL.") |
| 57 | + |
| 58 | +(defvar *skk-preedit-buffer* nil |
| 59 | + "Buffer used for SKK preedit display.") |
| 60 | + |
39 | 61 | (defun mode-indicator (mode) |
40 | 62 | "Return mode indicator string for MODE." |
41 | 63 | (case mode |
@@ -87,17 +109,74 @@ Shows okurigana with * marker, e.g., '▽か*く' for 書く." |
87 | 109 | (t |
88 | 110 | nil)))) |
89 | 111 |
|
| 112 | +;;; Preedit floating window management |
| 113 | + |
| 114 | +(defun ensure-preedit-buffer () |
| 115 | + "Get or create the preedit display buffer." |
| 116 | + (or *skk-preedit-buffer* |
| 117 | + (let ((buffer (make-buffer "*SKK Preedit*" :temporary t :enable-undo-p nil))) |
| 118 | + (setf (variable-value 'line-wrap :buffer buffer) nil) |
| 119 | + (setf *skk-preedit-buffer* buffer)))) |
| 120 | + |
| 121 | +(defun delete-preedit-window () |
| 122 | + "Delete the current preedit floating window if it exists." |
| 123 | + (delete-popup-message *skk-preedit-window*) |
| 124 | + (setf *skk-preedit-window* nil)) |
| 125 | + |
| 126 | +(defun create-preedit-window (text) |
| 127 | + "Create a new floating window displaying TEXT at the henkan-start position." |
| 128 | + (let* ((state (get-skk-state)) |
| 129 | + (henkan-start (skk-henkan-start state)) |
| 130 | + (buffer (ensure-preedit-buffer)) |
| 131 | + ;; Calculate offset-x to position at henkan-start instead of cursor |
| 132 | + (offset-x (if henkan-start |
| 133 | + (- (point-column henkan-start) (point-column (current-point))) |
| 134 | + 0))) |
| 135 | + ;; Update buffer content |
| 136 | + (erase-buffer buffer) |
| 137 | + (insert-string (buffer-point buffer) text) |
| 138 | + (buffer-start (buffer-point buffer)) |
| 139 | + ;; Create floating window using public API |
| 140 | + (display-popup-message buffer |
| 141 | + :timeout nil |
| 142 | + :style (list :gravity :follow-cursor |
| 143 | + :use-border nil |
| 144 | + :offset-x offset-x |
| 145 | + :offset-y *skk-preedit-offset-y* |
| 146 | + :background-color *skk-preedit-background-color* |
| 147 | + :cursor-invisible t)))) |
| 148 | + |
| 149 | +(defun update-preedit-window (text) |
| 150 | + "Update the preedit window with new TEXT, creating if needed." |
| 151 | + (delete-preedit-window) |
| 152 | + (when (and text (plusp (length text))) |
| 153 | + (setf *skk-preedit-window* (create-preedit-window text)))) |
| 154 | + |
90 | 155 | (defun update-skk-display () |
91 | | - "Update SKK display in echo area." |
| 156 | + "Update SKK display based on current display style." |
92 | 157 | (let* ((state (get-skk-state)) |
93 | 158 | (display (build-preedit-display state))) |
94 | | - (if display |
95 | | - (message "~A" display) |
96 | | - (message nil)))) |
| 159 | + (case *skk-preedit-display-style* |
| 160 | + (:floating-window |
| 161 | + (update-preedit-window display)) |
| 162 | + (:echo-area |
| 163 | + (if display |
| 164 | + (message "~A" display) |
| 165 | + (message nil))) |
| 166 | + (t |
| 167 | + ;; Default to floating-window |
| 168 | + (update-preedit-window display))))) |
97 | 169 |
|
98 | 170 | (defun clear-skk-display () |
99 | | - "Clear SKK display from echo area." |
100 | | - (message nil)) |
| 171 | + "Clear SKK display." |
| 172 | + (case *skk-preedit-display-style* |
| 173 | + (:floating-window |
| 174 | + (delete-preedit-window)) |
| 175 | + (:echo-area |
| 176 | + (message nil)) |
| 177 | + (t |
| 178 | + (delete-preedit-window) |
| 179 | + (message nil)))) |
101 | 180 |
|
102 | 181 | (defun show-skk-info () |
103 | 182 | "Show detailed SKK state information (for debugging)." |
|
0 commit comments