ignore long (block) comments when selecting buffer name

[?]
Jul 25, 2023, 10:34 PM
QM5V4K7DTRL24Y6HQXJXEZJLLJLO7ICVCOZW2AT76XATBUGA5WOAC

Dependencies

  • [2] SM7UNXQM avoid some unnecessary allocations
  • [3] BSDXVB3H backport some doc updates and renames
  • [4] AQRAWL63 don't tolerate Lua comments when parsing commands
  • [5] VA7NGQLG ignore comments when selecting buffer name
  • [*] LRDM35CE app running again

Change contents

  • replacement in live.lua at line 238
    [3.219][2.38:199]()
    -- Return the first word, after skipping Lua comments.
    if not buf:match('^%s*%-%-') then
    return buf:match('^%s*(%S+)') -- avoid unnecessary allocations
    [3.219]
    [2.199]
    return first_noncomment_word(buf)
    end
    -- return the first word (separated by whitespace) that's not in a Lua comment
    -- or empty string if there's nothing
    -- ignore strings; we don't expect them to be the first word in a program
    function first_noncomment_word(str)
    local pos = 1
    while pos <= #str do -- not Unicode-aware; hopefully it doesn't need to be
    if str:sub(pos,pos) == '-' then
    -- skip any comments
    if str:sub(pos+1,pos+1) == '-' then
    -- definitely start of a comment
    local long_comment_header = str:match('^%[=*%[', pos+2)
    if long_comment_header then
    -- long comment
    local long_comment_trailer = long_comment_header:gsub('%[', ']')
    pos = str:find(long_comment_trailer, pos, --[[plain]]true)
    if pos == nil then return '' end -- incomplete comment; no first word
    pos = pos + #long_comment_trailer
    else
    -- line comment
    pos = str:find('\n', pos)
    if pos == nil then return '' end -- incomplete comment; no first word
    end
    end
    end
    -- any non-whitespace that's not a comment is the first word
    if str:sub(pos,pos):match('%s') then
    pos = pos+1
    else
    return str:match('^%S*', pos)
    end
  • replacement in live.lua at line 272
    [2.205][2.205:359]()
    -- wastefully strip out comments everywhere, not just at the start
    buf = buf:gsub('%-%-[^\n]*', '') -- line comments
    return buf:match('^%s*(%S+)')
    [2.205]
    [3.970]
    return ''
    end
    function test_first_noncomment_word()
    check_eq(first_noncomment_word(''), '', 'empty string')
    check_eq(first_noncomment_word('abc'), 'abc', 'single word')
    check_eq(first_noncomment_word('abc def'), 'abc', 'stop at space')
    check_eq(first_noncomment_word('abc\tdef'), 'abc', 'stop at tab')
    check_eq(first_noncomment_word('abc\ndef'), 'abc', 'stop at newline')
    check_eq(first_noncomment_word('-- abc\ndef'), 'def', 'ignore line comment')
    check_eq(first_noncomment_word('--[[abc]] def'), 'def', 'ignore block comment')
    check_eq(first_noncomment_word('--[[abc\n]] def'), 'def', 'ignore multi-line block comment')
    check_eq(first_noncomment_word('--[[abc\n--]] def'), 'def', 'ignore comment leader before block comment trailer')
    check_eq(first_noncomment_word('--[=[abc]=] def'), 'def', 'ignore long comment')
    check_eq(first_noncomment_word('--[=[abc]] def ]=] ghi'), 'ghi', 'ignore long comment containing block comment trailer')
    check_eq(first_noncomment_word('--[===[abc\n\ndef ghi\njkl]===]mno\npqr'), 'mno', 'ignore long comment containing block comment trailer')
    check_eq(first_noncomment_word('-'), '-', 'incomplete comment token')
    check_eq(first_noncomment_word('--abc'), '', 'incomplete line comment')
    check_eq(first_noncomment_word('--abc\n'), '', 'just a line comment')
    check_eq(first_noncomment_word('--abc\n '), '', 'just a line comment 2')
    check_eq(first_noncomment_word('--[ab\n'), '', 'incomplete block comment token is a line comment')
    check_eq(first_noncomment_word('--[[ab'), '', 'incomplete block comment')
    check_eq(first_noncomment_word('--[[ab\n]'), '', 'incomplete block comment 2')
    check_eq(first_noncomment_word('--[=[ab\n]] ]='), '', 'incomplete block comment 3')
    check_eq(first_noncomment_word('--[=[ab\n]] ]=]'), '', 'just a block comment')
    check_eq(first_noncomment_word('--[=[ab\n]] ]=] \n \n '), '', 'just a block comment 2')