<commit_before>if not manipulator_module then qerror('Only usable from within manipulator') end
local gui = require 'gui'

NICKNAME = {}
PROFNAME = {}

function draw_names(units)
    local p = gui.Painter.new_xy(2, 2, gps.dimx - 3, 2)
    p:string(tostring(#units), COLOR_LIGHTGREEN)
    p:string((' %s selected: '):format(#units == 1 and 'dwarf' or 'dwarves'))
    local last = 1
    for i, u in pairs(units) do
        local name = dfhack.TranslateName(u.name)
        if #name + p.x + 12 >= gps.dimx - 2 then
            break
        end
        last = i
        p:string(name, COLOR_WHITE)
        if i ~= #units then
            p:string(', ', COLOR_WHITE)
        end
    end
    if last ~= #units then
        p:string(('and %i more'):format(#units - last))
    end
end

name_callbacks = {
    [NICKNAME] = function(unit, name)
        dfhack.units.setNickname(unit._native, name)
    end,
    [PROFNAME] = function(unit, name)
        unit.custom_profession = name
    end,
}

function apply_batch(units, func, ...)
    for _, u in pairs(units) do
        func(u, ...)
        u.dirty = true
    end
end

batch_ops = defclass(batch_ops, gui.FramedScreen)
batch_ops.ATTRS = {
    focus_path = 'manipulator/batch',
    options = {
        {'Change nickname', 'edit_nickname'},
        {'Change profession name', 'edit_profname'},
        {'Enable all labors', 'enable_all'},
        {'Disable all labors', 'disable_all'},
        {'Revert labor changes', 'revert_changes'},
    },
    selection_pen = {fg = COLOR_WHITE, bg = COLOR_GREEN},
    frame_style = gui.BOUNDARY_FRAME,
    frame_title = 'Dwarf Manipulator - Batch Operations',
    frame_inset = 1,
}

function batch_ops:init(args)
    self.units = check_nil(args.units)
    self.sel_idx = 1
    self.empty = (#self.units == 0)
end

function batch_ops:onRenderBody(p)
    if self.empty then
        p:string('No dwarves selected!', COLOR_LIGHTRED)
        return
    end
    draw_names(self.units)
    for i = 1, #self.options do
        p:seek(0, i + 1):string(self.options[i][1], i == self.sel_idx and self.selection_pen or nil)
    end
end

function batch_ops:onInput(keys)
    if keys.LEAVESCREEN then
        self:dismiss()
        return
    end
    process_keys(keys)
    if self.empty then return end
    if keys.SELECT then
        self:callback(self.options[self.sel_idx][2])()
    elseif keys.CURSOR_UP or keys.CURSOR_DOWN then
        self.sel_idx = scroll_index(self.sel_idx, keys.CURSOR_UP and -1 or 1, 1, #self.options)
    elseif keys._MOUSE_L then
        local mx = gps.mouse_x
        local my = gps.mouse_y<commit_msg>Dismiss edit menu after selecting an option<commit_after>if not manipulator_module then qerror('Only usable from within manipulator') end
local gui = require 'gui'

NICKNAME = {}
PROFNAME = {}

function draw_names(units)
    local p = gui.Painter.new_xy(2, 2, gps.dimx - 3, 2)
    p:string(tostring(#units), COLOR_LIGHTGREEN)
    p:string((' %s selected: '):format(#units == 1 and 'dwarf' or 'dwarves'))
    local last = 1
    for i, u in pairs(units) do
        local name = dfhack.TranslateName(u.name)
        if #name + p.x + 12 >= gps.dimx - 2 then
            break
        end
        last = i
        p:string(name, COLOR_WHITE)
        if i ~= #units then
            p:string(', ', COLOR_WHITE)
        end
    end
    if last ~= #units then
        p:string(('and %i more'):format(#units - last))
    end
end

name_callbacks = {
    [NICKNAME] = function(unit, name)
        dfhack.units.setNickname(unit._native, name)
    end,
    [PROFNAME] = function(unit, name)
        unit.custom_profession = name
    end,
}

function apply_batch(units, func, ...)
    for _, u in pairs(units) do
        func(u, ...)
        u.dirty = true
    end
end

batch_ops = defclass(batch_ops, gui.FramedScreen)
batch_ops.ATTRS = {
    focus_path = 'manipulator/batch',
    options = {
        {'Change nickname', 'edit_nickname'},
        {'Change profession name', 'edit_profname'},
        {'Enable all labors', 'enable_all'},
        {'Disable all labors', 'disable_all'},
        {'Revert labor changes', 'revert_changes'},
    },
    selection_pen = {fg = COLOR_WHITE, bg = COLOR_GREEN},
    frame_style = gui.BOUNDARY_FRAME,
    frame_title = 'Dwarf Manipulator - Batch Operations',
    frame_inset = 1,
}

function batch_ops:init(args)
    self.units = check_nil(args.units)
    self.sel_idx = 1
    self.empty = (#self.units == 0)
end

function batch_ops:onRenderBody(p)
    if self.empty then
        p:string('No dwarves selected!', COLOR_LIGHTRED)
        return
    end
    draw_names(self.units)
    for i = 1, #self.options do
        p:seek(0, i + 1):string(self.options[i][1], i == self.sel_idx and self.selection_pen or nil)
    end
end

function batch_ops:onInput(keys)
    if keys.LEAVESCREEN then
        self:dismiss()
        return
    end
    process_keys(keys)
    if self.empty then return end
    if keys.SELECT then
        self:callback(self.options[self.sel_idx][2])()
        self:dismiss()
    elseif keys.CURSOR_UP or keys.CURSOR_DOWN then
        self.sel_idx = scroll_index(self.sel_idx, keys.CURSOR_UP and -1 or 1, 1, #self.options)
    elseif keys._MOUSE_L then
        local mx = gps.mouse_x
        local my = gps.mouse_y
{'fraction_non_alphanumeric': 0.12041088073045463, 'fraction_numerical': 0.007608902415826517, 'mean_word_length': 2.6463245492371708, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4414084', 'n_tokens_mistral': 1865, 'n_tokens_neox': 1821, 'n_words': 454}