From 2f105eac860d19c186b05a60417a1944e917e1b3 Mon Sep 17 00:00:00 2001 From: Kevin Zander Date: Sat, 11 Mar 2017 17:57:32 -0600 Subject: [PATCH] Move string functions out of awful.util into new gears.string (#1584) Update deprecated awful.util string function calls to gears.string calls --- lib/awful/hotkeys_popup/widget.lua | 5 +- lib/awful/menu.lua | 4 +- lib/awful/prompt.lua | 11 ++-- lib/awful/util.lua | 58 ++++++++++---------- lib/awful/widget/taglist.lua | 6 +-- lib/awful/widget/tasklist.lua | 7 +-- lib/gears/init.lua | 1 + lib/gears/string.lua | 87 ++++++++++++++++++++++++++++++ lib/menubar/init.lua | 3 +- lib/menubar/utils.lua | 3 +- lib/wibox/widget/textbox.lua | 4 +- spec/awful/util_spec.lua | 38 ------------- spec/gears/string_spec.lua | 32 +++++++++++ 13 files changed, 174 insertions(+), 85 deletions(-) create mode 100644 lib/gears/string.lua delete mode 100644 spec/awful/util_spec.lua create mode 100644 spec/gears/string_spec.lua diff --git a/lib/awful/hotkeys_popup/widget.lua b/lib/awful/hotkeys_popup/widget.lua index f22801d3..4042095c 100644 --- a/lib/awful/hotkeys_popup/widget.lua +++ b/lib/awful/hotkeys_popup/widget.lua @@ -13,6 +13,7 @@ local capi = { } local awful = require("awful") local gtable = require("gears.table") +local gstring = require("gears.string") local wibox = require("wibox") local beautiful = require("beautiful") local dpi = beautiful.xresources.apply_dpi @@ -329,7 +330,7 @@ function widget.new(args) joined_descriptions = joined_descriptions .. key.description .. (i~=#keys and "\n" or "") end -- +1 for group label: - local items_height = awful.util.linecount(joined_descriptions) * line_height + group_label_height + local items_height = gstring.linecount(joined_descriptions) * line_height + group_label_height local current_column local available_height_px = max_height_px local add_new_column = true @@ -392,7 +393,7 @@ function widget.new(args) end -- +1 for group label: current_column.height_px = (current_column.height_px or 0) + - awful.util.linecount(joined_labels)*line_height + group_label_height + gstring.linecount(joined_labels)*line_height + group_label_height if _add_new_column then table.insert(column_layouts, current_column) end diff --git a/lib/awful/menu.lua b/lib/awful/menu.lua index 35e21ee9..80560f27 100644 --- a/lib/awful/menu.lua +++ b/lib/awful/menu.lua @@ -10,7 +10,7 @@ local wibox = require("wibox") local button = require("awful.button") -local util = require("awful.util") +local gstring = require("gears.string") local gtable = require("gears.table") local spawn = require("awful.spawn") local tags = require("awful.tag") @@ -552,7 +552,7 @@ function menu.entry(parent, args) -- luacheck: no unused args local key = '' label:set_font(args.theme.font) label:set_markup(string.gsub( - util.escape(args.text), "&(%w)", + gstring.xml_escape(args.text), "&(%w)", function (l) key = string.lower(l) return "" .. l .. "" diff --git a/lib/awful/prompt.lua b/lib/awful/prompt.lua index 4cf0c761..4ae8a996 100644 --- a/lib/awful/prompt.lua +++ b/lib/awful/prompt.lua @@ -128,6 +128,7 @@ local akey = require("awful.key") local debug = require('gears.debug') local gtable = require("gears.table") local gcolor = require("gears.color") +local gstring = require("gears.string") local prompt = {} @@ -278,20 +279,20 @@ local function prompt_text_with_cursor(args) local underline = args.cursor_ul or "none" if args.selectall then - if #text == 0 then char = " " else char = util.escape(text) end + if #text == 0 then char = " " else char = gstring.xml_escape(text) end spacer = " " text_start = "" text_end = "" elseif #text < args.cursor_pos then char = " " spacer = "" - text_start = util.escape(text) + text_start = gstring.xml_escape(text) text_end = "" else - char = util.escape(text:sub(args.cursor_pos, args.cursor_pos)) + char = gstring.xml_escape(text:sub(args.cursor_pos, args.cursor_pos)) spacer = " " - text_start = util.escape(text:sub(1, args.cursor_pos - 1)) - text_end = util.escape(text:sub(args.cursor_pos + 1)) + text_start = gstring.xml_escape(text:sub(1, args.cursor_pos - 1)) + text_end = gstring.xml_escape(text:sub(args.cursor_pos + 1)) end local cursor_color = gcolor.ensure_pango_color(args.cursor_color) diff --git a/lib/awful/util.lua b/lib/awful/util.lua index 3ef5f45e..dc455563 100644 --- a/lib/awful/util.lua +++ b/lib/awful/util.lua @@ -16,6 +16,7 @@ local pairs = pairs local type = type local gtable = require("gears.table") local string = string +local gstring = require("gears.string") local grect = require("gears.geometry").rectangle local Gio = require("lgi").Gio local gcolor = require("gears.color") @@ -137,22 +138,27 @@ function util.eval(s) return assert(load(s))() end -local xml_entity_names = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; --- Escape a string from XML char. -- Useful to set raw text in textbox. +-- @deprecated util.escape -- @param text Text to escape. -- @return Escape text. +-- @see gears.string function util.escape(text) - return text and text:gsub("['&<>\"]", xml_entity_names) or nil + util.deprecate("gears.string.xml_escape", {deprecated_in=5}) + + return gstring.xml_escape(text) end -local xml_entity_chars = { lt = "<", gt = ">", nbsp = " ", quot = "\"", apos = "'", ndash = "-", mdash = "-", - amp = "&" }; --- Unescape a string from entities. +-- @deprecated util.unescape -- @param text Text to unescape. -- @return Unescaped text. +-- @see gears.string function util.unescape(text) - return text and text:gsub("&(%a+);", xml_entity_chars) or nil + util.deprecate("gears.string.xml_unescape", {deprecated_in=5}) + + return gstring.xml_unescape(text) end --- Check if a file is a Lua valid file. @@ -380,30 +386,27 @@ function util.table.hasitem(t, item) end --- Split a string into multiple lines +-- @deprecated util.linewrap -- @param text String to wrap. -- @param width Maximum length of each line. Default: 72. -- @param indent Number of spaces added before each wrapped line. Default: 0. -- @return The string with lines wrapped to width. +-- @see gears.string function util.linewrap(text, width, indent) - text = text or "" - width = width or 72 - indent = indent or 0 + util.deprecate("gears.string.linewrap", {deprecated_in=5}) - local pos = 1 - return text:gsub("(%s+)()(%S+)()", - function(_, st, word, fi) - if fi - pos > width then - pos = st - return "\n" .. string.rep(" ", indent) .. word - end - end) + return gstring.linewrap(text, width, indent) end --- Count number of lines in a string +-- @deprecated util.linecount -- @tparam string text Input string. -- @treturn int Number of lines. +-- @see gears.string function util.linecount(text) - return select(2, text:gsub('\n', '\n')) + 1 + util.deprecate("gears.string.linecount", {deprecated_in=5}) + + return gstring.linecount(text) end --- Get a sorted table with all integer keys from a table @@ -485,23 +488,22 @@ end -- Escape all special pattern-matching characters so that lua interprets them -- literally instead of as a character class. -- Source: http://stackoverflow.com/a/20778724/15690 +-- @deprecated util.quote_pattern +-- @see gears.string function util.quote_pattern(s) - -- All special characters escaped in a string: %%, %^, %$, ... - local patternchars = '['..("%^$().[]*+-?"):gsub("(.)", "%%%1")..']' - return string.gsub(s, patternchars, "%%%1") + util.deprecate("gears.string.quote_pattern", {deprecated_in=5}) + + return gstring.quote_pattern(s) end -- Generate a pattern matching expression that ignores case. -- @param s Original pattern matching expression. +-- @deprecated util.query_to_pattern +-- @see gears.string function util.query_to_pattern(q) - local s = util.quote_pattern(q) - -- Poor man's case-insensitive character matching. - s = string.gsub(s, "%a", - function (c) - return string.format("[%s%s]", string.lower(c), - string.upper(c)) - end) - return s + util.deprecate("gears.string.query_to_pattern", {deprecated_in=5}) + + return gstring.query_to_pattern(q) end --- Round a number to an integer. diff --git a/lib/awful/widget/taglist.lua b/lib/awful/widget/taglist.lua index f2f589ed..9b1ab01b 100644 --- a/lib/awful/widget/taglist.lua +++ b/lib/awful/widget/taglist.lua @@ -15,13 +15,13 @@ local pairs = pairs local ipairs = ipairs local table = table local common = require("awful.widget.common") -local util = require("awful.util") local tag = require("awful.tag") local beautiful = require("beautiful") local fixed = require("wibox.layout.fixed") local surface = require("gears.surface") local timer = require("gears.timer") local gcolor = require("gears.color") +local gstring = require("gears.string") local function get_screen(s) return s and capi.screen[s] @@ -330,9 +330,9 @@ function taglist.taglist_label(t, args) text = "" if fg_color then text = text .. "" .. (util.escape(t.name) or "") .. "" + "'>" .. (gstring.xml_escape(t.name) or "") .. "" else - text = text .. (util.escape(t.name) or "") + text = text .. (gstring.xml_escape(t.name) or "") end text = text .. "" end diff --git a/lib/awful/widget/tasklist.lua b/lib/awful/widget/tasklist.lua index 3384c820..cfb10425 100644 --- a/lib/awful/widget/tasklist.lua +++ b/lib/awful/widget/tasklist.lua @@ -37,11 +37,11 @@ local setmetatable = setmetatable local table = table local common = require("awful.widget.common") local beautiful = require("beautiful") -local util = require("awful.util") local tag = require("awful.tag") local flex = require("wibox.layout.flex") local timer = require("gears.timer") local gcolor = require("gears.color") +local gstring = require("gears.string") local function get_screen(s) return s and screen[s] @@ -264,9 +264,10 @@ local function tasklist_label(c, args, tb) if not disable_task_name then if c.minimized then - name = name .. (util.escape(c.icon_name) or util.escape(c.name) or util.escape("")) + name = name .. (gstring.xml_escape(c.icon_name) or gstring.xml_escape(c.name) or + gstring.xml_escape("")) else - name = name .. (util.escape(c.name) or util.escape("")) + name = name .. (gstring.xml_escape(c.name) or gstring.xml_escape("")) end end diff --git a/lib/gears/init.lua b/lib/gears/init.lua index 2b28ce7d..7bac6732 100644 --- a/lib/gears/init.lua +++ b/lib/gears/init.lua @@ -20,6 +20,7 @@ return geometry = require("gears.geometry"); math = require("gears.math"); table = require("gears.table"); + string = require("gears.string"); } -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/lib/gears/string.lua b/lib/gears/string.lua new file mode 100644 index 00000000..00b181eb --- /dev/null +++ b/lib/gears/string.lua @@ -0,0 +1,87 @@ +--------------------------------------------------------------------------- +--- String module for gears +-- +-- @module gears.string +--------------------------------------------------------------------------- + +local gstring = {} + +local xml_entity_names = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; +--- Escape a string from XML char. +-- Useful to set raw text in textbox. +-- @class function +-- @name escape +-- @param text Text to escape. +-- @return Escape text. +function gstring.xml_escape(text) + return text and text:gsub("['&<>\"]", xml_entity_names) or nil +end + +local xml_entity_chars = { lt = "<", gt = ">", nbsp = " ", quot = "\"", apos = "'", ndash = "-", mdash = "-", + amp = "&" }; +--- Unescape a string from entities. +-- @class function +-- @name unescape +-- @param text Text to unescape. +-- @return Unescaped text. +function gstring.xml_unescape(text) + return text and text:gsub("&(%a+);", xml_entity_chars) or nil +end + +--- Count number of lines in a string +-- @class function +-- @name linecount +-- @tparam string text Input string. +-- @treturn int Number of lines. +function gstring.linecount(text) + return select(2, text:gsub('\n', '\n')) + 1 +end + +--- Split a string into multiple lines +-- @class function +-- @name linewrap +-- @param text String to wrap. +-- @param width Maximum length of each line. Default: 72. +-- @param indent Number of spaces added before each wrapped line. Default: 0. +-- @return The string with lines wrapped to width. +function gstring.linewrap(text, width, indent) + text = text or "" + width = width or 72 + indent = indent or 0 + + local pos = 1 + return text:gsub("(%s+)()(%S+)()", + function(_, st, word, fi) + if fi - pos > width then + pos = st + return "\n" .. string.rep(" ", indent) .. word + end + end) +end + +--- Escape all special pattern-matching characters so that lua interprets them +-- literally instead of as a character class. +-- Source: http://stackoverflow.com/a/20778724/15690 +-- @class function +-- @name quote_pattern +function gstring.quote_pattern(s) + -- All special characters escaped in a string: %%, %^, %$, ... + local patternchars = '['..("%^$().[]*+-?"):gsub("(.)", "%%%1")..']' + return string.gsub(s, patternchars, "%%%1") +end + +--- Generate a pattern matching expression that ignores case. +-- @param s Original pattern matching expression. +-- @class function +-- @name query_to_pattern +function gstring.query_to_pattern(q) + local s = gstring.quote_pattern(q) + -- Poor man's case-insensitive character matching. + s = string.gsub(s, "%a", + function (c) + return string.format("[%s%s]", string.lower(c), + string.upper(c)) + end) + return s +end +return gstring diff --git a/lib/menubar/init.lua b/lib/menubar/init.lua index ee2bd90a..72f617b2 100644 --- a/lib/menubar/init.lua +++ b/lib/menubar/init.lua @@ -31,6 +31,7 @@ local common = require("awful.widget.common") local theme = require("beautiful") local wibox = require("wibox") local gcolor = require("gears.color") +local gstring = require("gears.string") local function get_screen(s) return s and capi.screen[s] @@ -224,7 +225,7 @@ end local function menulist_update(scr) local query = instance.query or "" shownitems = {} - local pattern = awful.util.query_to_pattern(query) + local pattern = gstring.query_to_pattern(query) -- All entries are added to a list that will be sorted -- according to the priority (first) and weight (second) of its diff --git a/lib/menubar/utils.lua b/lib/menubar/utils.lua index 596dea57..044724e0 100644 --- a/lib/menubar/utils.lua +++ b/lib/menubar/utils.lua @@ -20,6 +20,7 @@ local glib = lgi.GLib local wibox = require("wibox") local debug = require("gears.debug") local protected_call = require("gears.protected_call") +local gstring = require("gears.string") local utils = {} @@ -305,7 +306,7 @@ end -- @tparam number|screen s Screen -- @treturn int Text width. function utils.compute_text_width(text, s) - return utils.compute_textbox_width(wibox.widget.textbox(awful_util.escape(text)), s) + return utils.compute_textbox_width(wibox.widget.textbox(gstring.escape(text)), s) end return utils diff --git a/lib/wibox/widget/textbox.lua b/lib/wibox/widget/textbox.lua index 74ed71ff..87039d88 100644 --- a/lib/wibox/widget/textbox.lua +++ b/lib/wibox/widget/textbox.lua @@ -118,7 +118,7 @@ end --- Set the text of the textbox (with -- [Pango markup](https://developer.gnome.org/pango/stable/PangoMarkupFormat.html)). -- @tparam string text The text to set. This can contain pango markup (e.g. --- `bold`). You can use `awful.util.escape` to escape +-- `bold`). You can use `gears.string.escape` to escape -- parts of it. -- @treturn[1] boolean true -- @treturn[2] boolean false @@ -146,7 +146,7 @@ end -- [Pango markup](https://developer.gnome.org/pango/stable/PangoMarkupFormat.html)). -- @property markup -- @tparam string text The text to set. This can contain pango markup (e.g. --- `bold`). You can use `awful.util.escape` to escape +-- `bold`). You can use `gears.string.escape` to escape -- parts of it. -- @see text diff --git a/spec/awful/util_spec.lua b/spec/awful/util_spec.lua deleted file mode 100644 index b2d9f065..00000000 --- a/spec/awful/util_spec.lua +++ /dev/null @@ -1,38 +0,0 @@ ---------------------------------------------------------------------------- --- @author Uli Schlachter --- @copyright 2015 Uli Schlachter ---------------------------------------------------------------------------- - -local util = require("awful.util") - -describe("awful.util", function() - describe("quote_pattern", function() - it("text", function() - assert.is.equal(util.quote_pattern("text"), "text") - end) - - it("do.t", function() - assert.is.equal(util.quote_pattern("do.t"), "do%.t") - end) - - it("per%cen[tage", function() - assert.is.equal(util.quote_pattern("per%cen[tage"), "per%%cen%[tage") - end) - end) - - describe("query_to_pattern", function() - it("DownLow", function() - assert.is.equal(string.match("DownLow", util.query_to_pattern("downlow")), "DownLow") - end) - - it("%word", function() - assert.is.equal(string.match("%word", util.query_to_pattern("%word")), "%word") - end) - - it("Substring of DownLow", function() - assert.is.equal(string.match("DownLow", util.query_to_pattern("ownl")), "ownL") - end) - end) -end) - --- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/spec/gears/string_spec.lua b/spec/gears/string_spec.lua new file mode 100644 index 00000000..817bdbed --- /dev/null +++ b/spec/gears/string_spec.lua @@ -0,0 +1,32 @@ + +local gstring = require("gears.string") + +describe("gears.string", function() + describe("quote_pattern", function() + it("text", function() + assert.is.equal(gstring.quote_pattern("text"), "text") + end) + + it("do.t", function() + assert.is.equal(gstring.quote_pattern("do.t"), "do%.t") + end) + + it("per%cen[tage", function() + assert.is.equal(gstring.quote_pattern("per%cen[tage"), "per%%cen%[tage") + end) + end) + + describe("query_to_pattern", function() + it("DownLow", function() + assert.is.equal(string.match("DownLow", gstring.query_to_pattern("downlow")), "DownLow") + end) + + it("%word", function() + assert.is.equal(string.match("%word", gstring.query_to_pattern("%word")), "%word") + end) + + it("Substring of DownLow", function() + assert.is.equal(string.match("DownLow", gstring.query_to_pattern("ownl")), "ownL") + end) + end) +end)