From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Newsgroups: gmane.emacs.bugs Subject: bug#29456: [PATCH] Add command for cycling between CSS color formats Date: Sun, 26 Nov 2017 16:21:51 +0100 Message-ID: <1511709711.2341.0@smtp.gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-kcsKK7l//BZQd9NVfWnf" X-Trace: blaine.gmane.org 1511709801 22359 195.159.176.226 (26 Nov 2017 15:23:21 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sun, 26 Nov 2017 15:23:21 +0000 (UTC) Cc: Tom Tromey , Stefan Monnier To: 29456@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sun Nov 26 16:23:15 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 1eIym3-0005Lt-0N for geb-bug-gnu-emacs@m.gmane.org; Sun, 26 Nov 2017 16:23:15 +0100 Original-Received: from localhost ([::1]:57003 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eIymA-0001YJ-7N for geb-bug-gnu-emacs@m.gmane.org; Sun, 26 Nov 2017 10:23:22 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:46680) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eIylu-0001Vh-76 for bug-gnu-emacs@gnu.org; Sun, 26 Nov 2017 10:23:07 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eIylq-0000wW-5p for bug-gnu-emacs@gnu.org; Sun, 26 Nov 2017 10:23:06 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:50771) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eIylq-0000wP-10 for bug-gnu-emacs@gnu.org; Sun, 26 Nov 2017 10:23:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1eIylp-0006oW-Np for bug-gnu-emacs@gnu.org; Sun, 26 Nov 2017 10:23:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 26 Nov 2017 15:23:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 29456 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.151170973426114 (code B ref -1); Sun, 26 Nov 2017 15:23:01 +0000 Original-Received: (at submit) by debbugs.gnu.org; 26 Nov 2017 15:22:14 +0000 Original-Received: from localhost ([127.0.0.1]:59452 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eIyl4-0006n7-DE for submit@debbugs.gnu.org; Sun, 26 Nov 2017 10:22:14 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:55581) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eIyl0-0006mq-LA for submit@debbugs.gnu.org; Sun, 26 Nov 2017 10:22:11 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eIyku-0000lD-4U for submit@debbugs.gnu.org; Sun, 26 Nov 2017 10:22:05 -0500 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:56717) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eIykt-0000l7-Va for submit@debbugs.gnu.org; Sun, 26 Nov 2017 10:22:04 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:46552) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eIyks-0001OZ-An for bug-gnu-emacs@gnu.org; Sun, 26 Nov 2017 10:22:03 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eIyko-0000iC-4V for bug-gnu-emacs@gnu.org; Sun, 26 Nov 2017 10:22:02 -0500 Original-Received: from mail-lf0-x22d.google.com ([2a00:1450:4010:c07::22d]:45405) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eIykn-0000gS-Lu for bug-gnu-emacs@gnu.org; Sun, 26 Nov 2017 10:21:58 -0500 Original-Received: by mail-lf0-x22d.google.com with SMTP id f131so21971306lff.12 for ; Sun, 26 Nov 2017 07:21:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:subject:to:cc:message-id:mime-version; bh=mrKyEUoEVbcYYCddCyexZ0VlpVqu7cLNxTgrJzUpFfs=; b=rhi3rCbOT4uwJGjRyhPp301YlqoZEhmmZR0mIKSpzpJrmJwwh/ZcEhii6d69ltCOkW OAQxSCp/ropEp7MY8W8fAQeNjYv5Et7WTs+tN5c0uAaxs7bCXM50uZNDvdQ8Qg2fIlqX I3UjNKi05hNiNf33h7iZ6LLYEPn9vYBjc8UNFHLHK5s5P+iGYtaP883gEQX4xxfm+Y4H qCaInGt9ccv27uSmVlxLJZFjKu8Zqqe2CEgcwZ9Xi1jfXQY7x2ew52qLA0hdxdw/adJw MSIVCNLWMlJc0xsmKOA5t8+jFkrC1avUsd6+kBfiIPASvM9eQudCRxkFh/t6StenP+bZ 1OQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:subject:to:cc:message-id:mime-version; bh=mrKyEUoEVbcYYCddCyexZ0VlpVqu7cLNxTgrJzUpFfs=; b=O7c2dFpwCnzCkulb5B6U8NHZCdPlgzkDbVtRQWSPw/b6dTi4TY12nqlIGnEqFEZMXf 4iSi+UlSFDevwbykJAR8LU/wMZP4aL49WJrmsFtV5+CcgVfYdCjFWFFjARzmtgcAJlaQ 2MCS29VsDHUU+vHh1oMImKLuXEZiTalh0xxewoIPWH4KS9IYsZV0mvkyV7BvlGpCwqBc UR3bSrLSMo8vUgV2IvGmrXsthZkU8XBu06mNl+TQPrjXGG043NTpULq0j9BDTKKMFv/2 yi8BjUgmtxfTmpoo5D77gIBRnGzWLILhFYJZheqET3NqXvXeMsKCYdTroDC7xIXS6/ct m2Bg== X-Gm-Message-State: AJaThX4ZXaql+eNgwImB8iLK0PNh27llQs4+/L8nVr9hYhGshzscGPec t4ZskL8e6SGdc747LPOU5vx8ew== X-Google-Smtp-Source: AGs4zMbAHsOR0ZcLpPRQldC2smX9c4ersnrAjgPxBWY7sbj0xywcHj1DFtXF458AA7VW4PB7QRFC6Q== X-Received: by 10.25.87.210 with SMTP id l201mr6581257lfb.101.1511709715535; Sun, 26 Nov 2017 07:21:55 -0800 (PST) Original-Received: from [192.168.100.8] (cm-84.210.143.4.getinternet.no. [84.210.143.4]) by smtp.gmail.com with ESMTPSA id k69sm4466128lfg.63.2017.11.26.07.21.52 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 26 Nov 2017 07:21:54 -0800 (PST) X-Mailer: geary/0.12-dev X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x 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:140410 Archived-At: --=-kcsKK7l//BZQd9NVfWnf Content-Type: multipart/alternative; boundary="=-9vqaxKBQ/2EMX1OwhFN5" --=-9vqaxKBQ/2EMX1OwhFN5 Content-Type: text/plain; charset=us-ascii; format=flowed The attached patch adds a new command 'css-cycle-color-format' to CSS mode, for cycling between color formats (e.g. "black" => "#000000" => "rgb(0, 0, 0)" => "black"), bound to 'C-c C-f'. I'll install the patch after a while unless there are any comments. -- Simen --=-9vqaxKBQ/2EMX1OwhFN5 Content-Type: text/html; charset=us-ascii
The attached patch adds a new command 'css-cycle-color-format' to CSS
mode, for cycling between color formats (e.g. "black" => "#000000" =>
"rgb(0, 0, 0)" => "black"), bound to 'C-c C-f'.

I'll install the patch after a while unless there are any comments.

-- Simen
--=-9vqaxKBQ/2EMX1OwhFN5-- --=-kcsKK7l//BZQd9NVfWnf Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Add-command-for-cycling-between-CSS-color-formats.patch Content-Transfer-Encoding: quoted-printable >From 54f258b39822d7042c240fe6bbde63ccfb49e59d Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Simen=3D20Heggest=3DC3=3DB8yl?=3D Date: Sun, 17 Sep 2017 20:08:18 +0200 Subject: [PATCH] Add command for cycling between CSS color formats * lisp/textmodes/css-mode.el (css-mode-map): Add keybinding for `css-cycle-color-format'. (css--web-color-to-4-dpc, css-named-color-to-hex) (css-hex-to-rgb, css-rgb-to-named-color-or-hex): New functions. (css-cycle-color-format): New command for cycling between color formats. * test/lisp/textmodes/css-mode-tests.el (css-test-web-color-to-4-dpc): (css-test-named-color-to-hex, css-test-hex-to-rgb) (css-test-rgb-to-named-color-or-hex, css-test-cycle-color-format): New tests for the functions mentioned above. * etc/NEWS: Mention the new command. --- etc/NEWS | 7 ++++ lisp/textmodes/css-mode.el | 79 +++++++++++++++++++++++++++++++= +++- test/lisp/textmodes/css-mode-tests.el | 53 +++++++++++++++++++++++ 3 files changed, 138 insertions(+), 1 deletion(-) diff --git a/etc/NEWS b/etc/NEWS index c47ca42d27..ab9f285740 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -63,6 +63,13 @@ whether '"' is also replaced in 'electric-quote-mode'. = If non-nil, =0C * Changes in Specialized Modes and Packages in Emacs 27.1 =20 +** CSS mode + +--- +*** A new command 'css-cycle-color-format' for cycling between color +formats (e.g. "black" =3D> "#000000" =3D> "rgb(0, 0, 0)") has been added, +bound to 'C-c C-f'. + ** Dired =20 +++ diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 93ca36b08a..aafcf8ade1 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -32,12 +32,13 @@ =20 ;;; Code: =20 -(require 'eww) (require 'cl-lib) (require 'color) +(require 'eww) (require 'seq) (require 'sgml-mode) (require 'smie) +(require 'thingatpt) (eval-when-compile (require 'subr-x)) =20 (defgroup css nil @@ -806,6 +807,7 @@ css-mode-syntax-table (defvar css-mode-map (let ((map (make-sparse-keymap))) (define-key map [remap info-lookup-symbol] 'css-lookup-symbol) + (define-key map "\C-c\C-f" 'css-cycle-color-format) map) "Keymap used in `css-mode'.") =20 @@ -1383,6 +1385,81 @@ css-completion-at-point (progn (insert ": ;") (forward-char -1)))))))))) =20 +(defun css--web-color-to-4-dpc (hex) + "Convert HEX web color to four digits per component. +Web colors use one or two digits per component for RGB hex +values. Convert the given color to four digits per component." + (let ((six-digits (=3D (length hex) 7))) + (apply + #'concat + `("#" + ,@(seq-mapcat + (apply-partially #'make-list (if six-digits 2 4)) + (seq-partition (seq-drop hex 1) (if six-digits 2 1))))))) + +(defun css-named-color-to-hex () + "Convert named color at point to hex format. +Return non-nil if a conversion was made." + (save-excursion + (unless (or (looking-at css--colors-regexp) + (eq (char-before) ?#)) + (backward-word)) + (when (member (word-at-point) (mapcar #'car css--color-map)) + (looking-at css--colors-regexp) + (let ((color (css--compute-color (point) (match-string 0)))) + (replace-match color)) + t))) + +(defun css-hex-to-rgb () + "Convert hex color at point to RGB format. +Return non-nil if a conversion was made." + (save-excursion + (unless (eq (char-after) ?#) + (backward-sexp)) + (when-let* ((hex (when (looking-at css--colors-regexp) + (css--compute-color (point) (match-string 0))))) + (seq-let (r g b) + (mapcar (lambda (x) (round (* x 255))) + (color-name-to-rgb (css--web-color-to-4-dpc hex))) + (replace-match (format "rgb(%d, %d, %d)" r g b))) + t))) + +(defun css-rgb-to-named-color-or-hex () + "Convert RGB color at point to a named color or hex format. +Convert to a named color if the color at point has a name, else +convert to hex format. Return non-nil if a conversion was made." + (save-excursion + (when-let* ((open-paren-pos (nth 1 (syntax-ppss)))) + (when (save-excursion + (goto-char open-paren-pos) + (looking-back "rgb" 3)) + (goto-char (nth 1 (syntax-ppss))))) + (when (eq (char-before) ?\)) + (backward-sexp)) + (skip-chars-backward "rgb") + (when (looking-at css--colors-regexp) + (let* ((start (match-end 0)) + (color (save-excursion + (goto-char start) + (css--compute-color start (match-string 0))))) + (when color + (kill-sexp) + (kill-sexp) + (let ((named-color (seq-find (lambda (x) (equal (cdr x) color)) + css--color-map))) + (insert (if named-color (car named-color) color))) + t))))) + +(defun css-cycle-color-format () + "Cycle the color at point between different formats. +Supported formats are by name (if possible), hexadecimal, and +RGB." + (interactive) + (or (css-named-color-to-hex) + (css-hex-to-rgb) + (css-rgb-to-named-color-or-hex) + (message "It doesn't look like a color at point"))) + ;;;###autoload (define-derived-mode css-mode prog-mode "CSS" "Major mode to edit Cascading Style Sheets (CSS). diff --git a/test/lisp/textmodes/css-mode-tests.el b/test/lisp/textmodes/cs= s-mode-tests.el index 47cf5f9244..be1ed55e42 100644 --- a/test/lisp/textmodes/css-mode-tests.el +++ b/test/lisp/textmodes/css-mode-tests.el @@ -244,6 +244,59 @@ css-mode-tests--completions (should (member "body" completions)) (should-not (member "article" completions))))) =20 +(ert-deftest css-test-web-color-to-4-dpc () + (should (equal (css--web-color-to-4-dpc "#ffffff") + (css--web-color-to-4-dpc "#fff"))) + (should (equal (css--web-color-to-4-dpc "#aabbcc") + (css--web-color-to-4-dpc "#abc"))) + (should (equal (css--web-color-to-4-dpc "#fab") + "#ffffaaaabbbb")) + (should (equal (css--web-color-to-4-dpc "#fafbfc") + "#fafafbfbfcfc"))) + +(ert-deftest css-test-named-color-to-hex () + (dolist (item '(("black" "#000000") + ("white" "#ffffff") + ("salmon" "#fa8072"))) + (with-temp-buffer + (css-mode) + (insert (nth 0 item)) + (css-named-color-to-hex) + (should (equal (buffer-string) (nth 1 item)))))) + +(ert-deftest css-test-hex-to-rgb () + (dolist (item '(("#000" "rgb(0, 0, 0)") + ("#000000" "rgb(0, 0, 0)") + ("#fff" "rgb(255, 255, 255)") + ("#ffffff" "rgb(255, 255, 255)"))) + (with-temp-buffer + (css-mode) + (insert (nth 0 item)) + (css-hex-to-rgb) + (should (equal (buffer-string) (nth 1 item)))))) + +(ert-deftest css-test-rgb-to-named-color-or-hex () + (dolist (item '(("rgb(0, 0, 0)" "black") + ("rgb(255, 255, 255)" "white") + ("rgb(255, 255, 240)" "ivory") + ("rgb(18, 52, 86)" "#123456"))) + (with-temp-buffer + (css-mode) + (insert (nth 0 item)) + (css-rgb-to-named-color-or-hex) + (should (equal (buffer-string) (nth 1 item)))))) + +(ert-deftest css-test-cycle-color-format () + (with-temp-buffer + (css-mode) + (insert "black") + (css-cycle-color-format) + (should (equal (buffer-string) "#000000")) + (css-cycle-color-format) + (should (equal (buffer-string) "rgb(0, 0, 0)")) + (css-cycle-color-format) + (should (equal (buffer-string) "black")))) + (ert-deftest css-mdn-symbol-guessing () (dolist (item '(("@med" "ia" "@media") ("@keyframes " "{" "@keyframes") --=20 2.15.0 = --=-kcsKK7l//BZQd9NVfWnf--