aboutsummaryrefslogtreecommitdiff
path: root/plugins/linenumbers.lua
blob: 03b5fb2922cea1bbab4403a2528c4fbdfe204e9a (plain)
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
-- mod-version:3
local config = require "core.config"
local style = require "core.style"
local DocView = require "core.docview"
local common = require "core.common"
local command = require "core.command"

config.plugins.linenumbers = common.merge({
  show = true,
  relative = false,
  -- The config specification used by the settings gui
  config_spec = {
    name = "Line Numbers",
    {
      label = "Show Numbers",
      description = "Display or hide the line numbers.",
      path = "show",
      type = "toggle",
      default = true
    },
    {
      label = "Relative Line Numbers",
      description = "Display relative line numbers starting from active line.",
      path = "relative",
      type = "toggle",
      default = false
    }
  }
}, config.plugins.linenumbers)

local draw_line_gutter = DocView.draw_line_gutter
local get_width = DocView.get_gutter_width

function DocView:draw_line_gutter(line, x, y, width)
  local lh = self:get_line_height()
  if not config.plugins.linenumbers.show then
    return lh
  end

  if config.plugins.linenumbers.relative then

    local color = style.line_number
    local local_idx = line
    local align = "right"

    local l1 = self.doc:get_selection(false)
    if line == l1 then
      color = style.line_number2
      if config.line_numbers then
        align = "center"
      else
        local_idx = 0
      end
    else
      local_idx = math.abs(line - l1)
    end

    -- Fix for old version (<=1.16)
    if width == nil then
      local gpad = style.padding.x * 2
      local gw = self:get_font():get_width(#self.doc.lines) + gpad
      width = gpad and gw - gpad or gw
    end

    common.draw_text(
      self:get_font(),
      color, local_idx, align,
      x + style.padding.x,
      y + self:get_line_text_y_offset(),
      width,  lh
    )
  else
    draw_line_gutter(self, line, x, y, width)
  end
  return lh
end

function DocView:get_gutter_width(...)
  if
    not config.plugins.linenumbers.show
    and
    not config.plugins.linenumbers.relative
  then
    return style.padding.x
  else
    return get_width(self, ...)
  end
end

command.add(nil, {
  ["line-numbers:toggle"]  = function()
    config.plugins.linenumbers.show = not config.plugins.linenumbers.show
  end,

  ["line-numbers:disable"] = function()
    config.plugins.linenumbers.show = false
  end,

  ["line-numbers:enable"]  = function()
    config.plugins.linenumbers.show = true
  end,

  ["relative-line-numbers:toggle"]  = function()
    config.plugins.linenumbers.relative = not config.plugins.linenumbers.relative
  end,

  ["relative-line-numbers:enable"]  = function()
    config.plugins.linenumbers.relative = true
  end,

  ["relative-line-numbers:disable"]  = function()
    config.plugins.linenumbers.relative = false
  end
})