Support DECSCUSR control function

* eat.el (eat-very-visible-vertical-bar-cursor-type)
(eat-vertical-bar-cursor-type, eat-horizontal-bar-cursor-type)
(eat-very-visible-horizontal-bar-cursor-type): New user
options.
* eat.el (eat--t-term): New slot 'cur-visible-p'.  Remove slot
'cur-blinking-p'.  Change the default value of 'cur-state' to
':block'.
* eat.el (eat--t-reset): Don't reset slot 'cur-blinking-p'.
Reset slot 'cur-visible-p'.  Reset 'cur-state' to ':block'.
Reset cursor state to ':block'.
* eat.el (eat--t-set-cursor-state): Set slot 'cur-visible-p' to
the current visibility of cursor.  Set slot 'cur-state' to the
shape of cursor, regardless of visibility.
* eat.el (eat--t-default-cursor): Rename to
'eat--t-show-cursor'.  Don't change any cursor state except
visibility.
* eat.el (eat--t-invisible-cursor): Rename to
'eat--t-hide-cursor'.  Don't change any cursor state except
visibility.
* eat.el (eat--t-set-cursor-style): New function.
* eat.el (eat--t-blinking-cursor, eat--t-non-blinking-cursor):
Update to handle new cursor shapes properly.
* eat.el (eat--t-set-modes): Call 'eat--t-show-cursor' instead
of 'eat--t-default-cursor'.
* eat.el (eat--t-reset-modes): Call 'eat--t-hide-cursor'
instead of 'eat--t-invisible-cursor'.
* eat.el (eat--t-handle-output): Handle DECSCUSR control
function.
* eat.el (eat-term-cursor-type): Return ':invisible' if cursor
is invisible, otherwise the value of slot 'cur-state'.  Update
the list of possible cursor states in the docstring.
* eat.el (eat-term-set-cursor-function): Update the list of
possible cursor states and fallback cursor state in the
docstring.
* eat.el (eat--cursor-blink-mode): Add
'eat--cursor-blink-stop-timers' to 'kill-buffer-hook'.
* eat.el (eat--set-cursor): Support new cursor states.  Update
the list of possible cursor states in the docstring.
* eat.texi (Cursor Types): Document new user options
'eat-vertical-bar-cursor-type',
'eat-very-visible-vertical-bar-cursor-type',
'eat-horizontal-bar-cursor-type' and
'eat-very-visible-horizontal-bar-cursor-type'.
This commit is contained in:
Akib Azmain Turja 2023-03-31 17:51:15 +06:00
parent 644d01f6fd
commit b986063994
No known key found for this signature in database
GPG key ID: 5535FCF54D88616B
2 changed files with 194 additions and 62 deletions

218
eat.el
View file

@ -376,9 +376,8 @@ prompt annotation."
,cur-type)) ,cur-type))
"Custom type specification for Eat's cursor type variables.") "Custom type specification for Eat's cursor type variables.")
(defcustom eat-default-cursor-type (defcustom eat-invisible-cursor-type '(nil nil nil)
`(,(default-value 'cursor-type) nil nil) "Type of cursor to use as invisible cursor in Eat buffer.
"Cursor to use in Eat buffer.
The value is a list of form (CURSOR-ON BLINKING-FREQUENCY CURSOR-OFF). The value is a list of form (CURSOR-ON BLINKING-FREQUENCY CURSOR-OFF).
@ -390,8 +389,9 @@ should be nil when cursor is not blinking."
:group 'eat-ui :group 'eat-ui
:group 'eat-eshell) :group 'eat-eshell)
(defcustom eat-invisible-cursor-type '(nil nil nil) (defcustom eat-default-cursor-type
"Invisible cursor to use in Eat buffer. `(,(default-value 'cursor-type) nil nil)
"Cursor to use in Eat buffer.
The value is a list of form (CURSOR-ON BLINKING-FREQUENCY CURSOR-OFF). The value is a list of form (CURSOR-ON BLINKING-FREQUENCY CURSOR-OFF).
@ -407,9 +407,64 @@ should be nil when cursor is not blinking."
`(,(default-value 'cursor-type) 2 hollow) `(,(default-value 'cursor-type) 2 hollow)
"Very visible cursor to use in Eat buffer. "Very visible cursor to use in Eat buffer.
When the cursor is invisible, the car of the value is used as The value is a list of form (CURSOR-ON BLINKING-FREQUENCY CURSOR-OFF).
`cursor-type', which see. The cdr of the value, when non-nil, is the
blinking frequency of cursor." When the cursor is on, CURSOR-ON is used as `cursor-type', which see.
BLINKING-FREQUENCY is the blinking frequency of cursor's blinking.
When the cursor is off, CURSOR-OFF is used as `cursor-type'. This
should be nil when cursor is not blinking."
:type eat--cursor-type-value-type
:group 'eat-ui
:group 'eat-eshell)
(defcustom eat-vertical-bar-cursor-type '(bar nil nil)
"Vertical bar cursor to use in Eat buffer.
The value is a list of form (CURSOR-ON BLINKING-FREQUENCY CURSOR-OFF).
When the cursor is on, CURSOR-ON is used as `cursor-type', which see.
BLINKING-FREQUENCY is the blinking frequency of cursor's blinking.
When the cursor is off, CURSOR-OFF is used as `cursor-type'. This
should be nil when cursor is not blinking."
:type eat--cursor-type-value-type
:group 'eat-ui
:group 'eat-eshell)
(defcustom eat-very-visible-vertical-bar-cursor-type '(bar 2 nil)
"Very visible vertical bar cursor to use in Eat buffer.
The value is a list of form (CURSOR-ON BLINKING-FREQUENCY CURSOR-OFF).
When the cursor is on, CURSOR-ON is used as `cursor-type', which see.
BLINKING-FREQUENCY is the blinking frequency of cursor's blinking.
When the cursor is off, CURSOR-OFF is used as `cursor-type'. This
should be nil when cursor is not blinking."
:type eat--cursor-type-value-type
:group 'eat-ui
:group 'eat-eshell)
(defcustom eat-horizontal-bar-cursor-type '(hbar nil nil)
"Horizontal bar cursor to use in Eat buffer.
The value is a list of form (CURSOR-ON BLINKING-FREQUENCY CURSOR-OFF).
When the cursor is on, CURSOR-ON is used as `cursor-type', which see.
BLINKING-FREQUENCY is the blinking frequency of cursor's blinking.
When the cursor is off, CURSOR-OFF is used as `cursor-type'. This
should be nil when cursor is not blinking."
:type eat--cursor-type-value-type
:group 'eat-ui
:group 'eat-eshell)
(defcustom eat-very-visible-horizontal-bar-cursor-type '(hbar 2 nil)
"Very visible horizontal bar cursor to use in Eat buffer.
The value is a list of form (CURSOR-ON BLINKING-FREQUENCY CURSOR-OFF).
When the cursor is on, CURSOR-ON is used as `cursor-type', which see.
BLINKING-FREQUENCY is the blinking frequency of cursor's blinking.
When the cursor is off, CURSOR-OFF is used as `cursor-type'. This
should be nil when cursor is not blinking."
:type eat--cursor-type-value-type :type eat--cursor-type-value-type
:group 'eat-ui :group 'eat-ui
:group 'eat-eshell) :group 'eat-eshell)
@ -964,8 +1019,8 @@ Nil when not in alternative display mode.")
(g2 . us-ascii) (g2 . us-ascii)
(g3 . us-ascii)))) (g3 . us-ascii))))
:documentation "Current character set.") :documentation "Current character set.")
(cur-state :default :documentation "Current state of cursor.") (cur-state :block :documentation "Current state of cursor.")
(cur-blinking-p nil :documentation "Is the cursor blinking?") (cur-visible-p t :documentation "Is the cursor visible?")
(saved-face (saved-face
(1value (eat--t-make-face)) (1value (eat--t-make-face))
:documentation "Saved SGR attributes.") :documentation "Saved SGR attributes.")
@ -1047,8 +1102,8 @@ Don't `set' it, bind it to a value with `let'.")
(g3 . dec-line-drawing))) (g3 . dec-line-drawing)))
(setf (eat--t-term-saved-face eat--t-term) (eat--t-make-face)) (setf (eat--t-term-saved-face eat--t-term) (eat--t-make-face))
(setf (eat--t-term-bracketed-yank eat--t-term) nil) (setf (eat--t-term-bracketed-yank eat--t-term) nil)
(setf (eat--t-term-cur-state eat--t-term) :default) (setf (eat--t-term-cur-state eat--t-term) :block)
(setf (eat--t-term-cur-blinking-p eat--t-term) nil) (setf (eat--t-term-cur-visible-p eat--t-term) t)
(setf (eat--t-term-title eat--t-term) "") (setf (eat--t-term-title eat--t-term) "")
(setf (eat--t-term-keypad-mode eat--t-term) nil) (setf (eat--t-term-keypad-mode eat--t-term) nil)
(setf (eat--t-term-mouse-mode eat--t-term) nil) (setf (eat--t-term-mouse-mode eat--t-term) nil)
@ -1062,7 +1117,7 @@ Don't `set' it, bind it to a value with `let'.")
eat--t-term nil) eat--t-term nil)
(funcall (eat--t-term-set-title-fn eat--t-term) eat--t-term "") (funcall (eat--t-term-set-title-fn eat--t-term) eat--t-term "")
(funcall (eat--t-term-set-cursor-fn eat--t-term) eat--t-term (funcall (eat--t-term-set-cursor-fn eat--t-term) eat--t-term
:default))) :block)))
(defun eat--t-cur-right (&optional n) (defun eat--t-cur-right (&optional n)
"Move cursor N columns right. "Move cursor N columns right.
@ -1893,36 +1948,64 @@ to (1, 1). When N is 3, also erase the scrollback."
(defun eat--t-set-cursor-state (state) (defun eat--t-set-cursor-state (state)
"Set cursor state to STATE. "Set cursor state to STATE.
STATE one of the `:default', `:invisible', `:very-visible'." STATE one of the `:invisible', `:block', `:blinking-block',
(unless (eq (eat--t-term-cur-state eat--t-term) state) `:underline', `:blinking-underline', `:bar', `:blinking-bar'."
;; Update state. (if (eq state :invisible)
(setf (eat--t-term-cur-state eat--t-term) state) (when (eat--t-term-cur-visible-p eat--t-term)
;; Inform the UI. (setf (eat--t-term-cur-visible-p eat--t-term) nil)
(funcall (eat--t-term-set-cursor-fn eat--t-term) eat--t-term (funcall (eat--t-term-set-cursor-fn eat--t-term) eat--t-term
state))) :invisible))
(unless (and (eat--t-term-cur-visible-p eat--t-term)
(eq (eat--t-term-cur-state eat--t-term) state))
;; Update state.
(setf (eat--t-term-cur-state eat--t-term) state)
(setf (eat--t-term-cur-visible-p eat--t-term) t)
;; Inform the UI.
(funcall (eat--t-term-set-cursor-fn eat--t-term) eat--t-term
state))))
(defun eat--t-default-cursor () (defun eat--t-set-cursor-style (style)
"Set the cursor to its default state." "Set cursor state as described by STYLE."
(eat--t-set-cursor-state (when (<= 0 style 6)
(if (eat--t-term-cur-blinking-p eat--t-term) (let ((state (aref [ :blinking-block :blinking-block :block
:very-visible :blinking-underline :underline
:default))) :blinking-bar :bar]
style)))
(if (eat--t-term-cur-visible-p eat--t-term)
(eat--t-set-cursor-state state)
(setf (eat--t-term-cur-state eat--t-term) state)))))
(defun eat--t-invisible-cursor () (defun eat--t-show-cursor ()
"Make the cursor visible."
(when (not (eat--t-term-cur-visible-p eat--t-term))
(eat--t-set-cursor-state (eat--t-term-cur-state eat--t-term))))
(defun eat--t-hide-cursor ()
"Make the cursor invisible." "Make the cursor invisible."
(eat--t-set-cursor-state :invisible)) (when (eat--t-term-cur-visible-p eat--t-term)
(eat--t-set-cursor-state :invisible)))
(defun eat--t-blinking-cursor () (defun eat--t-blinking-cursor ()
"Make the cursor blink." "Make the cursor blink."
(setf (eat--t-term-cur-blinking-p eat--t-term) t) (let ((state (pcase (eat--t-term-cur-state eat--t-term)
(when (eq (eat--t-term-cur-state eat--t-term) :default) (:block :blinking-block)
(eat--t-set-cursor-state :very-visible))) (:underline :blinking-underline)
(:bar :blinking-bar)
(state state))))
(if (eat--t-term-cur-visible-p eat--t-term)
(eat--t-set-cursor-state state)
(setf (eat--t-term-cur-state eat--t-term) state))))
(defun eat--t-non-blinking-cursor () (defun eat--t-non-blinking-cursor ()
"Make the cursor not blink." "Make the cursor not blink."
(setf (eat--t-term-cur-blinking-p eat--t-term) nil) (let ((state (pcase (eat--t-term-cur-state eat--t-term)
(when (eq (eat--t-term-cur-state eat--t-term) :very-visible) (:blinking-block :block)
(eat--t-set-cursor-state :default))) (:blinking-underline :underline)
(:blinking-bar :bar)
(state state))))
(if (eat--t-term-cur-visible-p eat--t-term)
(eat--t-set-cursor-state state)
(setf (eat--t-term-cur-state eat--t-term) state))))
(defun eat--t-enable-bracketed-yank () (defun eat--t-enable-bracketed-yank ()
"Enable bracketed yank mode." "Enable bracketed yank mode."
@ -2741,7 +2824,7 @@ is the selection data encoded in base64."
('(12) ('(12)
(eat--t-blinking-cursor)) (eat--t-blinking-cursor))
('(25) ('(25)
(eat--t-default-cursor)) (eat--t-show-cursor))
('(1000) ('(1000)
(eat--t-enable-normal-mouse)) (eat--t-enable-normal-mouse))
('(1002) ('(1002)
@ -2778,7 +2861,7 @@ is the selection data encoded in base64."
('(12) ('(12)
(eat--t-non-blinking-cursor)) (eat--t-non-blinking-cursor))
('(25) ('(25)
(eat--t-invisible-cursor)) (eat--t-hide-cursor))
(`(,(or 9 1000 1002 1003)) (`(,(or 9 1000 1002 1003))
(eat--t-disable-mouse)) (eat--t-disable-mouse))
('(1004) ('(1004)
@ -3103,6 +3186,9 @@ is the selection data encoded in base64."
;; CSI 6 n. ;; CSI 6 n.
('((?n) nil ((6))) ('((?n) nil ((6)))
(eat--t-device-status-report)) (eat--t-device-status-report))
;; CSI <n> SP q.
(`((?q ?\ ) nil ((,n)))
(eat--t-set-cursor-style n))
;; CSI <n> ; <n> r. ;; CSI <n> ; <n> r.
(`((?r) nil ,(and (pred listp) params)) (`((?r) nil ,(and (pred listp) params))
(eat--t-change-scroll-region (caadr params) (eat--t-change-scroll-region (caadr params)
@ -3479,10 +3565,16 @@ where FUNCTION is the input function."
The return value can be one of the following: The return value can be one of the following:
`:default' Default cursor.
`:invisible' Invisible cursor. `:invisible' Invisible cursor.
`:very-visible' Very visible cursor." `:block' Block (filled box) cursor (default).
(eat--t-term-cur-state terminal)) `:blinking-block' Blinking block cursor.
`:bar' Vertical bar cursor.
`:blinking-bar' Blinking vertical bar cursor.
`:underline' Horizontal bar cursor.
`:blinking-underline' Blinking horizontal bar cursor."
(if (eat--t-term-cur-visible-p terminal)
(eat--t-term-cur-state terminal)
:invisible))
(defun eat-term-set-cursor-function (terminal) (defun eat-term-set-cursor-function (terminal)
"Return the function used to set the cursor of TERMINAL. "Return the function used to set the cursor of TERMINAL.
@ -3491,14 +3583,17 @@ The function is called with two arguments, TERMINAL and a symbol STATE
describing the new state of cursor. The function should not change describing the new state of cursor. The function should not change
point and buffer restriction. STATE can be one of the following: point and buffer restriction. STATE can be one of the following:
`:default' Default cursor.
`:invisible' Invisible cursor. `:invisible' Invisible cursor.
`:very-visible' Very visible cursor. Can also be implemented `:block' Block (filled box) cursor (default).
as blinking cursor. `:blinking-block' Blinking block cursor.
`:bar' Vertical bar cursor.
`:blinking-bar' Blinking vertical bar cursor.
`:underline' Horizontal bar cursor.
`:blinking-underline' Blinking horizontal bar cursor.
More possible values might be added in future. So in case the More possible values might be added in future. So in case the
function doesn't know about a particular cursor state, it should reset function doesn't know about a particular cursor state, it should reset
the cursor to the default like the `:default' state. the cursor to the default like the `:block' state.
To set it, use (`setf' (`eat-term-set-cursor-function' TERMINAL) To set it, use (`setf' (`eat-term-set-cursor-function' TERMINAL)
FUNCTION), where FUNCTION is the function to set cursor." FUNCTION), where FUNCTION is the function to set cursor."
@ -4495,6 +4590,8 @@ return \"eat-color\", otherwise return \"eat-mono\"."
t) t)
(add-hook 'post-command-hook #'eat--cursor-blink-start-timers (add-hook 'post-command-hook #'eat--cursor-blink-start-timers
nil t) nil t)
(add-hook 'kill-buffer-hook #'eat--cursor-blink-stop-timers nil
t)
(when (current-idle-time) (when (current-idle-time)
(eat--cursor-blink-start-timers))) (eat--cursor-blink-start-timers)))
(t (t
@ -4503,6 +4600,8 @@ return \"eat-color\", otherwise return \"eat-mono\"."
t) t)
(remove-hook 'post-command-hook #'eat--cursor-blink-start-timers (remove-hook 'post-command-hook #'eat--cursor-blink-start-timers
t) t)
(remove-hook 'kill-buffer-hook #'eat--cursor-blink-stop-timers
t)
(mapc #'kill-local-variable locals))))) (mapc #'kill-local-variable locals)))))
@ -4539,18 +4638,29 @@ return \"eat-color\", otherwise return \"eat-mono\"."
STATE can be one of the following: STATE can be one of the following:
`:default' Default cursor. `:invisible' Invisible cursor.
`:invisible' Invisible cursor. `:block' Block (filled box) cursor (default).
`:very-visible' Very visible cursor. Can also be implemented as `:blinking-block' Blinking block cursor.
blinking cursor. `:bar' Vertical bar cursor.
Any other value Default cursor." `:blinking-bar' Blinking vertical bar cursor.
(setq-local eat--cursor-blink-type `:underline' Horizontal bar cursor.
(pcase state `:blinking-underline' Blinking horizontal bar cursor.
(:invisible eat-invisible-cursor-type) Any other value Block cursor."
(:very-visible eat-very-visible-cursor-type) (setq-local
(_ eat-default-cursor-type))) ; `:default' eat--cursor-blink-type
(pcase state
(:invisible eat-invisible-cursor-type)
(:block eat-default-cursor-type)
(:blinking-block eat-very-visible-cursor-type)
(:bar eat-vertical-bar-cursor-type)
(:blinking-bar eat-very-visible-vertical-bar-cursor-type)
(:underline eat-horizontal-bar-cursor-type)
(:blinking-underline eat-very-visible-horizontal-bar-cursor-type)
(_ eat-default-cursor-type)))
(setq-local cursor-type (car eat--cursor-blink-type)) (setq-local cursor-type (car eat--cursor-blink-type))
(eat--cursor-blink-mode (if (cadr eat--cursor-blink-type) +1 -1))) (when (xor (cadr eat--cursor-blink-type) eat--cursor-blink-mode)
(eat--cursor-blink-mode
(if (cadr eat--cursor-blink-type) +1 -1))))
(defun eat--manipulate-kill-ring (_ selection data) (defun eat--manipulate-kill-ring (_ selection data)
"Manipulate `kill-ring'. "Manipulate `kill-ring'.

View file

@ -2,7 +2,7 @@
@comment %**start of header @comment %**start of header
@setfilename eat.info @setfilename eat.info
@set UPDATED 29 March 2023 @set UPDATED 31 March 2023
@set VERSION 0.6.1 @set VERSION 0.6.1
@documentencoding UTF-8 @documentencoding UTF-8
@codequotebacktick on @codequotebacktick on
@ -562,23 +562,45 @@ types of cursor. Each of the user options share the same format.
@vindex eat-default-cursor-type @vindex eat-default-cursor-type
@defopt eat-default-cursor-type @defopt eat-default-cursor-type
This control the cursor shape of ``visible'' cursor type. This controls the cursor shape of the ``visible'' cursor type.
@end defopt @end defopt
@vindex eat-invisible-cursor-type @vindex eat-invisible-cursor-type
@defopt eat-invisible-cursor-type @defopt eat-invisible-cursor-type
This control the cursor shape of ``invisible'' cursor type. This controls the cursor shape of the ``invisible'' cursor type.
@end defopt @end defopt
@vindex eat-very-visible-cursor-type @vindex eat-very-visible-cursor-type
@defopt eat-very-visible-cursor-type @defopt eat-very-visible-cursor-type
This control the cursor shape of ``very visible'' cursor type. This This controls the cursor shape of the ``very visible'' cursor type.
cursor blinks, switching between the default cursor shape and a hollow This cursor blinks, switching between the default cursor shape and a
box. hollow box.
@end defopt @end defopt
The value type of these user options is a list. The list is of form @vindex eat-vertical-bar-cursor-type
(@var{cursor-on} @var{blinking-frequency} @var{cursor-off}). @defopt eat-vertical-bar-cursor-type
This controls the cursor shape of the ``vertical bar'' cursor type.
@end defopt
@vindex eat-very-visible-vertical-bar-cursor-type
@defopt eat-very-visible-vertical-bar-cursor-type
This controls the cursor shape of the ``very visible vertical bar''
cursor type. This cursor blinks.
@end defopt
@vindex eat-horizontal-bar-cursor-type
@defopt eat-horizontal-bar-cursor-type
This controls the cursor shape of the ``horizontal bar'' cursor type.
@end defopt
@vindex eat-very-visible-horizontal-bar-cursor-type
@defopt eat-very-visible-horizontal-bar-cursor-type
This controls the cursor shape of the ``very visible horizontal bar''
cursor type. This cursor blinks.
@end defopt
The value type of all these user options is a list. The list is of
form (@var{cursor-on} @var{blinking-frequency} @var{cursor-off}).
@var{blinking-frequency} is the frequency of blinking of cursor. It @var{blinking-frequency} is the frequency of blinking of cursor. It
is a number, controlling how many times the cursor will blink a is a number, controlling how many times the cursor will blink a
second. This can also be @code{nil}, this will disable cursor second. This can also be @code{nil}, this will disable cursor