is read-only; if not, it activates the on-screen keyboard, assuming
that the user is about to enter text in to the current buffer.
+@vindex touch-screen-always-display
+ The user option @code{touch-screen-display-keyboard} forces Emacs to
+always display the on screen keyboard; it may also be bound buffer
+locally, meaning to always display the keyboard when the buffer is
+selected.
+
Emacs also provides a set of functions to show or hide the on-screen
keyboard. For more details, @pxref{On-Screen Keyboards,,, elisp, The
Emacs Lisp Reference Manual}.
Where @var{ephemeral} is the buffer which was modified,
@var{beg} and @var{end} are the positions of the edit at the
time it was completed, and @var{ephemeral} is either a string,
-containing any text which was inserted, @code{t}, meaning that
-the edit is a temporary edit made by the input method, and
-@code{nil}, meaning that some text was deleted.
+containing any text which was inserted, or any text before point
+which was deleted, @code{t}, meaning that the edit is a
+temporary edit made by the input method, and @code{nil}, meaning
+that some text was deleted after point.
@vindex text-conversion-style
Whether or not this event is sent depends on the value of the
if (size >= 2)
{
button = buttons.get (1);
- dialog.setButton (DialogInterface.BUTTON_NEUTRAL,
+ dialog.setButton (DialogInterface.BUTTON_NEGATIVE,
button.name, button);
}
if (size >= 3)
{
button = buttons.get (2);
- dialog.setButton (DialogInterface.BUTTON_NEGATIVE,
+ dialog.setButton (DialogInterface.BUTTON_NEUTRAL,
button.name, button);
}
}
if (size >= 2)
{
button = buttons.get (1);
- dialog.setButton (DialogInterface.BUTTON_NEUTRAL,
- button.name, button);
buttonView
- = dialog.getButton (DialogInterface.BUTTON_NEUTRAL);
+ = dialog.getButton (DialogInterface.BUTTON_NEGATIVE);
buttonView.setEnabled (button.enabled);
}
{
button = buttons.get (2);
buttonView
- = dialog.getButton (DialogInterface.BUTTON_NEGATIVE);
+ = dialog.getButton (DialogInterface.BUTTON_NEUTRAL);
buttonView.setEnabled (button.enabled);
}
}
non-nil, this function is called. It move point to a new buffer
position, presumably skipping only whitespace in between.")
+(defun electric-pair-analyze-conversion (string)
+ "Notice that STRING has been deleted by an input method.
+If the last character of STRING is an electric pair character,
+and the character after point is too, then delete that other
+character."
+ (let* ((prev (aref string (1- (length string))))
+ (next (char-after))
+ (syntax-info (electric-pair-syntax-info prev))
+ (syntax (car syntax-info))
+ (pair (cadr syntax-info)))
+ (when (and next pair (memq syntax '(?\( ?\" ?\$))
+ (eq pair next))
+ (delete-char 1))))
+
(defun electric-pair--skip-whitespace ()
"Skip whitespace forward, not crossing comment or string boundaries."
(let ((saved (point))
;; Actually in textconv.c.
(defvar text-conversion-edits)
+;; Actually in elec-pair.el.
+(defvar electric-pair-preserve-balance)
+(declare-function electric-pair-analyze-conversion "elec-pair.el")
+
(defun analyze-text-conversion ()
"Analyze the results of the previous text conversion event.
line breaking of the previous line when `auto-fill-mode' is
enabled.
+ - Look for the deletion of a single electric pair character,
+ and delete the adjascent pair if
+ `electric-pair-delete-adjacent-pairs'.
+
- Run `post-self-insert-functions' for the last character of
any inserted text so that modes such as `electric-pair-mode'
can work."
(interactive)
- (dolist (edit text-conversion-edits)
+ ;; The list must be processed in reverse.
+ (dolist (edit (reverse text-conversion-edits))
;; Filter out ephemeral edits and deletions.
- (when (and (not (eq (nth 1 edit) (nth 2 edit)))
- (stringp (nth 3 edit)))
+ (when (and (stringp (nth 3 edit)))
(with-current-buffer (car edit)
- (let* ((inserted (nth 3 edit))
- ;; Get the first and last characters.
- (start (aref inserted 0))
- (end (aref inserted (1- (length inserted))))
- ;; Figure out whether or not to auto-fill.
- (auto-fill-p (or (aref auto-fill-chars start)
- (aref auto-fill-chars end)))
- ;; Figure out whether or not a newline was inserted.
- (newline-p (string-search "\n" inserted)))
- (save-excursion
- (if (and auto-fill-function newline-p)
- (progn (goto-char (nth 2 edit))
- (previous-logical-line)
- (funcall auto-fill-function))
- (when (and auto-fill-function auto-fill-p)
- (progn (goto-char (nth 2 edit))
- (funcall auto-fill-function)))))
- (goto-char (nth 2 edit))
- (let ((last-command-event end))
- (run-hooks 'post-self-insert-hook)))))))
+ (if (not (eq (nth 1 edit) (nth 2 edit)))
+ ;; Process this insertion. (nth 3 edit) is the text which
+ ;; was inserted.
+ (let* ((inserted (nth 3 edit))
+ ;; Get the first and last characters.
+ (start (aref inserted 0))
+ (end (aref inserted (1- (length inserted))))
+ ;; Figure out whether or not to auto-fill.
+ (auto-fill-p (or (aref auto-fill-chars start)
+ (aref auto-fill-chars end)))
+ ;; Figure out whether or not a newline was inserted.
+ (newline-p (string-search "\n" inserted))
+ ;; FIXME: this leads to an error in
+ ;; `atomic-change-group', seemingly because
+ ;; buffer-undo-list is being modified or
+ ;; prematurely truncated. Turn it off for now.
+ (electric-pair-preserve-balance nil))
+ (save-excursion
+ (if (and auto-fill-function newline-p)
+ (progn (goto-char (nth 2 edit))
+ (previous-logical-line)
+ (funcall auto-fill-function))
+ (when (and auto-fill-function auto-fill-p)
+ (progn (goto-char (nth 2 edit))
+ (funcall auto-fill-function)))))
+ (goto-char (nth 2 edit))
+ (let ((last-command-event end))
+ (run-hooks 'post-self-insert-hook)))
+ ;; Process this deletion before point. (nth 2 edit) is the
+ ;; text which was deleted. Input methods typically prefer
+ ;; to edit words instead of deleting characters off their
+ ;; ends, but they seem to always send proper requests for
+ ;; deletion for punctuation.
+ (when (and (boundp 'electric-pair-delete-adjacent-pairs)
+ (symbol-value 'electric-pair-delete-adjacent-pairs)
+ ;; Make sure elec-pair is loaded.
+ (fboundp 'electric-pair-analyze-conversion)
+ ;; Only do this if only a single edit happened.
+ text-conversion-edits)
+ (save-excursion
+ (goto-char (nth 2 edit))
+ (electric-pair-analyze-conversion (nth 3 edit)))))))))
\f
(setq-local term-last-input-end (make-marker))
(setq-local term-last-input-match "")
+ ;; Always display the onscreen keyboard.
+ (setq-local touch-screen-display-keyboard t)
+
;; These local variables are set to their local values:
(make-local-variable 'term-saved-home-marker)
(make-local-variable 'term-saved-cursor)
"Timer used to track long-presses.
This is always cleared upon any significant state change.")
+(defcustom touch-screen-display-keyboard nil
+ "If non-nil, always display the on screen keyboard.
+A buffer local value means to always display the on screen
+keyboard when the buffer is selected."
+ :type 'boolean
+ :group 'mouse
+ :version "30.1")
+
(defcustom touch-screen-delay 0.7
"Delay in seconds before Emacs considers a touch to be a long-press."
:type 'number
(call-interactively command nil
(vector event))
(when (memq command touch-screen-set-point-commands)
- (if (not (or buffer-read-only
- (get-text-property (point) 'read-only)))
+ (if (and (or (not buffer-read-only)
+ touch-screen-display-keyboard)
+ ;; Detect the splash screen and avoid
+ ;; displaying the on screen keyboard
+ ;; there.
+ (not (equal (buffer-name) "*GNU Emacs*")))
;; Once the on-screen keyboard has been opened,
;; add `touch-screen-window-selection-changed'
;; as a window selection change function This
}
else
{
- /* Delete the text between the start of the composition region
- and its end. TODO: avoid this widening. */
- record_unwind_protect (save_restriction_restore,
- save_restriction_save ());
- Fwiden ();
+ /* Delete the text between the start of the composing region and
+ its end. */
start = marker_position (f->conversion.compose_region_start);
end = marker_position (f->conversion.compose_region_end);
del_range (start, end);
specpdl_ref count;
ptrdiff_t start, end, a, b, a1, b1, lstart, rstart;
struct window *w;
+ Lisp_Object text;
/* If F's old selected window is no longer live, fail. */
start = max (BEGV, lstart - left);
end = min (ZV, rstart + right);
- del_range (start, end);
- record_buffer_change (start, start, Qnil);
+ text = del_range_1 (start, end, false, true);
+ record_buffer_change (start, start, text);
}
else
{
- start = max (BEGV, lstart - left);
- end = lstart;
-
- del_range (start, end);
- record_buffer_change (start, start, Qnil);
+ /* Don't record a deletion if the text which was deleted lies
+ after point. */
start = rstart;
end = min (ZV, rstart + right);
- del_range (start, end);
- record_buffer_change (start, start, Qnil);
+ text = del_range_1 (start, end, false, true);
+ record_buffer_change (start, start, Qnil);
+
+ /* Now delete what must be deleted on the left. */
+
+ start = max (BEGV, lstart - left);
+ end = lstart;
+ text = del_range_1 (start, end, false, true);
+ record_buffer_change (start, start, text);
}
/* if the mark is now equal to start, deactivate it. */
DEFSYM (Qtext_conversion, "text-conversion");
DEFSYM (Qpush_mark, "push-mark");
DEFSYM (Qunderline, "underline");
- DEFSYM (Qoverriding_text_conversion_style, "overriding-text-conversion-style");
+ DEFSYM (Qoverriding_text_conversion_style,
+ "overriding-text-conversion-style");
DEFVAR_LISP ("text-conversion-edits", Vtext_conversion_edits,
doc: /* List of buffers that were last edited as a result of text conversion.
place; otherwise, it is a string describing the text which was
inserted.
-If a deletion occured, then BEG and END are the same, and EPHEMERAL is
-nil. */);
+If a deletion occured before point, then BEG and END are the same, and
+EPHEMERAL is the text which was deleted.
+
+If a deletion occured after point, then BEG and END are also the same,
+but EPHEMERAL is nil.
+
+The list contents are ordered later edits first, so you must iterate
+through the list in reverse. */);
Vtext_conversion_edits = Qnil;
DEFVAR_LISP ("overriding-text-conversion-style",