File: init.lua

package info (click to toggle)
vifm 0.14.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 14,252 kB
  • sloc: ansic: 179,567; sh: 5,445; makefile: 723; perl: 347; python: 76; xml: 26
file content (143 lines) | stat: -rw-r--r-- 3,986 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
--[[

Puts cursor on a recently modified/changed/accessed entry in current view,
which frees from the need to change and restore 'sort' to do it otherwise.

Adds the following mappings:

* [count]rm -- puts cursor on a [count]'s recently modified entry
* [count]rc -- puts cursor on a [count]'s recently changed entry
* [count]ra -- puts cursor on a [count]'s recently accessed entry

--]]

local M = {}

local function make_entries_sorter(attr)
    -- sorts entries by `attr` and entry name in descending order
    return function(e1, e2)
        -- like -attr in 'sort'
        if e1[attr] ~= e2[attr] then
            return e1[attr] > e2[attr]
        -- like +dir in 'sort'
        elseif (e1.isdir and not e2.isdir) or (not e1.isdir and e2.isdir) then
            return e1.isdir
        -- like +name in 'sort'
        else
            return e1.name < e2.name
        end
    end
end

local function full_path(e)
    return e.location .. '/' .. e.name
end

local function recent_entry_index(attr, num)
    local currview = vifm.currview()
    local curr_entry = currview.cursor:entry()
    local curr_loc = curr_entry.location
    local entries = {}
    local entry_pos = {}

    local function remember_entry_and_position(e, pos)
        table.insert(entries, e)
        entry_pos[full_path(e)] = pos
    end

    if currview.custom == nil or currview.custom.type ~= 'tree' then
        for i = 1, currview.entrycount do
            local e = currview:entry(i)
            remember_entry_and_position(e, i)
        end
    else
        -- limit to location of current entry in tree-view

        remember_entry_and_position(curr_entry, currview.cursor.pos)

        local function belongs_to_curr_entry_location(i)
            local e = currview:entry(i)
            if e.location:sub(1, curr_loc:len()) ~= curr_loc then
                return false
            end
            if e.location == curr_loc then
                remember_entry_and_position(e, i)
            end
            return true
        end

        -- gather entries around the cursor
        local i = currview.cursor.pos - 1
        while i >= 1 and belongs_to_curr_entry_location(i) do
            i = i - 1
        end

        local i = currview.cursor.pos + 1
        while i <= currview.entrycount and belongs_to_curr_entry_location(i) do
            i = i + 1
        end
    end

    table.sort(entries, make_entries_sorter(attr))

    local num = math.max(num or 1, 1)
    local idx = math.min(num, #entries)
    return entry_pos[full_path(entries[idx])]
end

local function make_handler(attr)
    return function(info)
        vifm.currview().cursor.pos = recent_entry_index(attr, info.count)
    end
end

local function make_handler_selector(attr)
    return function(info)
        local currview = vifm.currview()

        local begin = recent_entry_index(attr, info.count)
        local end_ = currview.cursor.pos
        if begin > end_ then
            begin, end_ = end_, begin
        end

        local indexes = {}
        for i = begin, end_ do
            table.insert(indexes, i)
        end

        return {
            indexes = indexes,
            cursorpos = indexes[1],
        }
    end
end

local function add_key(key, attr, desc)
    local added = vifm.keys.add {
        shortcut = key,
        description = 'move cursor to recently ' .. desc .. ' entry',
        modes = { 'normal', 'visual' },
        handler = make_handler(attr),
    }
    if not added then
        vifm.sb.error('Failed to register ' .. key)
    end

    local added = vifm.keys.add {
        shortcut = key,
        description = 'move cursor to recently ' .. desc .. ' entry',
        modes = { 'normal' },
        isselector = true,
        handler = make_handler_selector(attr),
    }
    if not added then
        vifm.sb.error('Failed to register selector ' .. key)
    end
end

add_key('rm', 'mtime', 'modified')
add_key('rc', 'ctime', 'changed')
add_key('ra', 'atime', 'accessed')

return M