From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Michal Nazarewicz Newsgroups: gmane.emacs.bugs Subject: bug#25646: [PATCH 3/3] =?UTF-8?Q?Don=E2=80=99t?= assume character can be either upper- or lower-case when casing Date: Tue, 7 Feb 2017 19:05:41 +0100 Message-ID: <20170207180541.18025-3-mina86@mina86.com> References: <20170207180541.18025-1-mina86@mina86.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Trace: blaine.gmane.org 1486490804 21444 195.159.176.226 (7 Feb 2017 18:06:44 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 7 Feb 2017 18:06:44 +0000 (UTC) To: 25646@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Feb 07 19:06:40 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cbAA3-0005QM-35 for geb-bug-gnu-emacs@m.gmane.org; Tue, 07 Feb 2017 19:06:39 +0100 Original-Received: from localhost ([::1]:55757 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbAA8-0000FS-PF for geb-bug-gnu-emacs@m.gmane.org; Tue, 07 Feb 2017 13:06:44 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:55060) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbA9Y-0008SI-BM for bug-gnu-emacs@gnu.org; Tue, 07 Feb 2017 13:06:10 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cbA9T-0001Qd-FO for bug-gnu-emacs@gnu.org; Tue, 07 Feb 2017 13:06:08 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:32825) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cbA9T-0001QU-D6 for bug-gnu-emacs@gnu.org; Tue, 07 Feb 2017 13:06:03 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1cbA9T-0007Qm-5S for bug-gnu-emacs@gnu.org; Tue, 07 Feb 2017 13:06:03 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Michal Nazarewicz Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 07 Feb 2017 18:06:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 25646 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 25646-submit@debbugs.gnu.org id=B25646.148649075528537 (code B ref 25646); Tue, 07 Feb 2017 18:06:03 +0000 Original-Received: (at 25646) by debbugs.gnu.org; 7 Feb 2017 18:05:55 +0000 Original-Received: from localhost ([127.0.0.1]:59255 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cbA9L-0007QC-4R for submit@debbugs.gnu.org; Tue, 07 Feb 2017 13:05:55 -0500 Original-Received: from mail-wm0-f42.google.com ([74.125.82.42]:37117) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cbA9J-0007PY-7w for 25646@debbugs.gnu.org; Tue, 07 Feb 2017 13:05:53 -0500 Original-Received: by mail-wm0-f42.google.com with SMTP id v77so166082118wmv.0 for <25646@debbugs.gnu.org>; Tue, 07 Feb 2017 10:05:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=242TMgdUGdVn9xTo07DKeJ6moN9zyvo/gwfs32TpZJQ=; b=FjgwtWSAcJwMRl4RS6QnPDK8AOow4UkXsNSp/KhXtC8wPy2qVcPZMy2xGiKIBO3YTX ihqv22d6bU009b+O73yVWtzS2LS1HZEEWkXBPmHdar0Dji9rVHOBlJB3SuUlMOG91bgu mdCv3rqCD1ekCTb2fnKQLdJzAdI3r2POMsYfiz017wLX2ct0NcCc1ghvQV/eQobu791I 6EgvMcfaqq5TKMlhPHWVYHZYzvLQ6QYicuIUPVWg+r3hT9XQZlN93zHQQU+nySQ5N352 9uFgFwFNWKJjMoaA7UQb4mIYY9cnRjVi1I0v6EALT8ZsEgma/Q78JLA5qqGvP2fgd61g zrCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=242TMgdUGdVn9xTo07DKeJ6moN9zyvo/gwfs32TpZJQ=; b=rzeWYvxGSs86dYm6aW3+uiDXmDxRwEHmw9qvPHh6JlbNGTN51M2b8tbxWycOAHNmeU aMhojHlljXmTAdC1mkFDds8hU8lPIJVX301ug6whx1/Mgm+JEifxVocGzUFnT/cNktRN wABF3WnUUz/3sBegWuQi16TKpMZ9qFxSEVxDhOvFQYP39XwIHNgqeeX+vAW73HgnjEK9 K63E6HJqoZJ0Hhl96bXwJ1O6aGKWBTxzTXpHyCiNPbNV6B/cT1Gwl1/qF/xxSaP6RsTs W6FsgXB3iq8RUencEbhQ2v2YoDC8kcBBvTuqownXQotQIla3P236c424DIVuImzXkz9G kW2w== X-Gm-Message-State: AIkVDXJ/WQyPB6fUzlf1zkGOMAeZrOzQVPHwTA9oR0e46dLLvZoZSi+96rHb8O8n+WqG25m0 X-Received: by 10.223.153.98 with SMTP id x89mr14887114wrb.181.1486490747273; Tue, 07 Feb 2017 10:05:47 -0800 (PST) Original-Received: from mpn.zrh.corp.google.com ([2620:0:105f:303:f498:9cb2:70ba:1c65]) by smtp.gmail.com with ESMTPSA id a72sm8528851wrc.48.2017.02.07.10.05.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 07 Feb 2017 10:05:45 -0800 (PST) Original-Received: by mpn.zrh.corp.google.com (Postfix, from userid 126942) id 3E8CD1E0270; Tue, 7 Feb 2017 19:05:42 +0100 (CET) X-Mailer: git-send-email 2.11.0.483.g087da7b7c-goog In-Reply-To: <20170207180541.18025-1-mina86@mina86.com> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:129092 Archived-At: A compatibility digraph characters, such as Dž, are neither upper- nor lower-case. At the moment however, those are reported as upper-case¹ despite the fact that they change when upper-cased. Stop checking if a character is upper-case before trying to up-case it so that title-case characters are handled correctly. ¹ Because they change when converted to lower-case. Notice an asymmetry in that for a character to be considered lower-case it must not be upper-case (plus the usual condition of changing when upper-cased). * src/buffer.h (upcase1): Delete. (upcase): Change to upcase character unconditionally just like downcase does it. This is what upcase1 was. * src/casefiddle.c (casify_object, casify_region): Use upcase instead of upcase1 and don’t check !uppercasep(x) before calling upcase. * src/keyboard.c (read_key_sequence): Don’t check if uppercase(x), just downcase(x) and see if it changed. * test/src/casefiddle-tests.el (casefiddle-tests--characters, casefiddle-tests-casing): Update test cases which are now passing. --- etc/NEWS | 8 +++++++- src/buffer.h | 18 +++++++++--------- src/casefiddle.c | 20 +++++++------------- src/keyboard.c | 25 +++++++++++++++---------- test/src/casefiddle-tests.el | 8 ++++---- 5 files changed, 42 insertions(+), 37 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index da0b5388837..16e1ddd495e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -338,6 +338,12 @@ same as in modes where the character is not whitespace. Instead of only checking the modification time, Emacs now also checks the file's actual content before prompting the user. +** Title case characters are properly converted to upper case. +'upcase', 'upcase-region' et al. convert title case characters (such +as Dz) into their upper case form (such as DZ). As a downside, +'capitalize' and 'upcase-initials' produce awkward words where first +two letters are upper case, e.g. DŽungla (instead of Džungla). + * Changes in Specialized Modes and Packages in Emacs 26.1 @@ -1017,7 +1023,7 @@ along with GNU Emacs. If not, see . Local variables: -coding: us-ascii +coding: utf-8 mode: outline paragraph-separate: "[ ]*$" end: diff --git a/src/buffer.h b/src/buffer.h index 4a23e4fdd2e..f53212e3120 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -1365,28 +1365,28 @@ downcase (int c) return NATNUMP (down) ? XFASTINT (down) : c; } -/* True if C is upper case. */ -INLINE bool uppercasep (int c) { return downcase (c) != c; } - -/* Upcase a character C known to be not upper case. */ +/* Upcase a character C, or make no change if that cannot be done. */ INLINE int -upcase1 (int c) +upcase (int c) { Lisp_Object upcase_table = BVAR (current_buffer, upcase_table); Lisp_Object up = CHAR_TABLE_REF (upcase_table, c); return NATNUMP (up) ? XFASTINT (up) : c; } +/* True if C is upper case. */ +INLINE bool uppercasep (int c) +{ + return downcase (c) != c; +} + /* True if C is lower case. */ INLINE bool lowercasep (int c) { - return !uppercasep (c) && upcase1 (c) != c; + return !uppercasep (c) && upcase (c) != c; } -/* Upcase a character C, or make no change if that cannot be done. */ -INLINE int upcase (int c) { return uppercasep (c) ? c : upcase1 (c); } - INLINE_HEADER_END #endif /* EMACS_BUFFER_H */ diff --git a/src/casefiddle.c b/src/casefiddle.c index 28ffcb298ff..b2b87e7a858 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c @@ -64,13 +64,9 @@ casify_object (enum case_action flag, Lisp_Object obj) multibyte = 1; if (! multibyte) MAKE_CHAR_MULTIBYTE (c1); - c = downcase (c1); - if (inword) - XSETFASTINT (obj, c | flags); - else if (c == (XFASTINT (obj) & ~flagbits)) + c = flag == CASE_DOWN ? downcase (c1) : upcase (c1); + if (c != c1) { - if (! inword) - c = upcase1 (c1); if (! multibyte) MAKE_CHAR_UNIBYTE (c); XSETFASTINT (obj, c | flags); @@ -95,7 +91,7 @@ casify_object (enum case_action flag, Lisp_Object obj) c = downcase (c); else if (!uppercasep (c) && (!inword || flag != CASE_CAPITALIZE_UP)) - c = upcase1 (c1); + c = upcase (c1); if ((int) flag >= (int) CASE_CAPITALIZE) inword = (SYNTAX (c) == Sword); if (c != c1) @@ -127,9 +123,8 @@ casify_object (enum case_action flag, Lisp_Object obj) c = STRING_CHAR_AND_LENGTH (SDATA (obj) + i_byte, len); if (inword && flag != CASE_CAPITALIZE_UP) c = downcase (c); - else if (!uppercasep (c) - && (!inword || flag != CASE_CAPITALIZE_UP)) - c = upcase1 (c); + else if (!inword || flag != CASE_CAPITALIZE_UP) + c = upcase (c); if ((int) flag >= (int) CASE_CAPITALIZE) inword = (SYNTAX (c) == Sword); o += CHAR_STRING (c, o); @@ -236,9 +231,8 @@ casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e) c2 = c; if (inword && flag != CASE_CAPITALIZE_UP) c = downcase (c); - else if (!uppercasep (c) - && (!inword || flag != CASE_CAPITALIZE_UP)) - c = upcase1 (c); + else if (!inword || flag != CASE_CAPITALIZE_UP) + c = upcase (c); if ((int) flag >= (int) CASE_CAPITALIZE) inword = ((SYNTAX (c) == Sword) && (inword || !syntax_prefix_flag_p (c))); diff --git a/src/keyboard.c b/src/keyboard.c index a86e7c5f8e4..3f6298f4362 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -9642,22 +9642,26 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, use the corresponding lower-case letter instead. */ if (NILP (current_binding) && /* indec.start >= t && fkey.start >= t && */ keytran.start >= t - && INTEGERP (key) - && ((CHARACTERP (make_number (XINT (key) & ~CHAR_MODIFIER_MASK)) - && uppercasep (XINT (key) & ~CHAR_MODIFIER_MASK)) - || (XINT (key) & shift_modifier))) + && INTEGERP (key)) { Lisp_Object new_key; + int k = XINT (key); + + if (k & shift_modifier) + XSETINT (new_key, k & ~shift_modifier); + else if (CHARACTERP (make_number (k & ~CHAR_MODIFIER_MASK))) + { + int dc = downcase(k & ~CHAR_MODIFIER_MASK); + if (dc == (k & ~CHAR_MODIFIER_MASK)) + goto not_upcase; + XSETINT (new_key, dc | (k & CHAR_MODIFIER_MASK)); + } + else + goto not_upcase; original_uppercase = key; original_uppercase_position = t - 1; - if (XINT (key) & shift_modifier) - XSETINT (new_key, XINT (key) & ~shift_modifier); - else - XSETINT (new_key, (downcase (XINT (key) & ~CHAR_MODIFIER_MASK) - | (XINT (key) & CHAR_MODIFIER_MASK))); - /* We have to do this unconditionally, regardless of whether the lower-case char is defined in the keymaps, because they might get translated through function-key-map. */ @@ -9668,6 +9672,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, goto replay_sequence; } + not_upcase: if (NILP (current_binding) && help_char_p (EVENT_HEAD (key)) && t > 1) { diff --git a/test/src/casefiddle-tests.el b/test/src/casefiddle-tests.el index e2399664f47..1588cdbbd2b 100644 --- a/test/src/casefiddle-tests.el +++ b/test/src/casefiddle-tests.el @@ -63,13 +63,13 @@ casefiddle-tests--characters (?Ł ?Ł ?ł ?Ł) (?ł ?Ł ?ł ?Ł) - ;; FIXME: We should have: + ;; FIXME: Commented one is what we want. ;;(?DŽ ?DŽ ?dž ?Dž) - ;; but instead we have: (?DŽ ?DŽ ?dž ?DŽ) - ;; FIXME: Those two are broken at the moment: ;;(?Dž ?DŽ ?dž ?Dž) + (?Dž ?DŽ ?dž ?DŽ) ;;(?dž ?DŽ ?dž ?Dž) + (?dž ?DŽ ?dž ?DŽ) (?Σ ?Σ ?σ ?Σ) (?σ ?Σ ?σ ?Σ) @@ -197,7 +197,7 @@ casefiddle-tests--test-casing ;;("ΌΣΟΣ" "ΌΣΟΣ" "όσος" "Όσος" "Όσος") ;; And here’s what is actually happening: ("DŽUNGLA" "DŽUNGLA" "džungla" "DŽungla" "DŽUNGLA") - ("Džungla" "DžUNGLA" "džungla" "Džungla" "Džungla") + ("Džungla" "DŽUNGLA" "džungla" "DŽungla" "DŽungla") ("džungla" "DŽUNGLA" "džungla" "DŽungla" "DŽungla") ("define" "DEfiNE" "define" "Define" "Define") ("fish" "fiSH" "fish" "fish" "fish") -- 2.11.0.483.g087da7b7c-goog