summaryrefslogtreecommitdiff
path: root/support/digestif/digestif/config.lua
blob: 8b901ba93d4dcbe0f5ba47b9e4e27d379875c9b4 (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
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
144
145
146
147
148
149
150
151
152
153
154
155
156
local util = require "digestif.util"
local format = string.format

local config = {}

config.version = "0.5"
local pre_version = os.getenv("DIGESTIF_PRERELEASE")
if pre_version then
  config.version = config.version .. "-" .. pre_version
end

if util.is_command("kpsewhich") then
  local pipe = io.popen("kpsewhich -var-brace-value=TEXMF")
  local output = pipe:read("l")
  local ok, exitt, exitc = pipe:close()
  if ok and exitt == "exit" and exitc == 0 then
    config.texmf_dirs = util.imap(
      function (s) return s:gsub("^!!", "") end,
      util.path_list_split(output)
    )
  elseif config.verbose then
    util.log("Error running kpsewhich (%s %d)", exitt, exitc)
  end
else -- TODO: What should be the default?
  config.texmf_dirs = {
    "/usr/local/share/texmf",
    "/usr/share/texmf",
    "/usr/share/texlive/texmf-local",
    "/usr/share/texlive/texmf-dist",
  }
end

config.data_dirs = {} -- TODO: What should be the default?

-- Location of a complete texmf distribution, used for instance to
-- find documentation not installed locally.  Passed to format with
-- one argument, the percent-encoded name of a file.
config.external_texmf = "https://www.tug.org/texlive/Contents/live/texmf-dist/%s"

config.provide_snippets = false

-- Table mapping command names to the snippet to be used, overriding
-- the default.
config.extra_snippets = {}

-- This allows the user to assign custom actions to generated command
-- tags.
config.extra_actions = {
  eqref = "ref"
}

config.fuzzy_cite = true
config.fuzzy_ref = true
config.info_command = util.is_command("info")

-- For candidates of these kinds, include the annotation in the
-- candidate label.  The values of this table are a string which is
-- formatted with two arguments, the candidate text and annotation.
config.lsp_long_candidates = {
  label = "%-12s    %s",
  bibitem = "%-12s    %s",
}

--* Loading user settings

local function is_table(key_type, val_type)
  return function(obj)
    if type(obj) ~= "table" then return false end
    for key, val in pairs(obj) do
      if type(key) ~= key_type then return false end
      if type(val) ~= val_type then return false end
    end
    return true
  end
end

local validators =   {
  data_dirs = is_table("number", "string"),
  extra_actions = is_table("string", "string"),
  extra_snippets = is_table("string", "string"),
  fuzzy_cite = "boolean",
  fuzzy_ref = "boolean",
  info_command = "string",
  lsp_long_candidates = is_table("string", "string"),
  provide_snippets = "boolean",
  texmf_dirs = is_table("number", "string"),
  tlpdb_path = "string",
  verbose = "boolean",
}

-- Set config entries found in `tbl`.
function config.load_from_table(tbl)
  -- Set verbose option before all others
  local verbose = tbl.verbose or config.verbose
  for key, val in pairs(tbl) do
    local validator, ok = validators[key]
    if type(validator) == "string" then
      ok = type(val) == validator
    elseif type(validator) == "function" then
      ok = validator(val)
    end
    if ok then
      config[key] = val
      if verbose then
        local msg = "Setting configuration option %s = %s"
        util.log(msg, key, util.inspect(val))
      end
    else
      local msg = "Invalid configuration option: %s = %s"
      error(format(msg, key, util.inspect(val)))
    end
  end
end

function config.load_from_file(file)
  local tbl = {}
  local ok, err = loadfile(file, "t", tbl)
  if ok then ok, err = pcall(ok) end
  if not ok then
    local msg = "Error loading configuration from %s: %s"
    error(msg, file, err)
  end
  config.load_from_table(tbl)
end

function config.load_from_env()
  local DIGESTIF_DATA = os.getenv("DIGESTIF_DATA")
  if DIGESTIF_DATA then
    config.data_dirs = util.path_list_split(DIGESTIF_DATA)
  end

  local DIGESTIF_TEXMF = os.getenv("DIGESTIF_TEXMF")
  if DIGESTIF_TEXMF then
    config.texmf_dirs = util.path_list_split(DIGESTIF_TEXMF)
  end

  local DIGESTIF_TLPDB = os.getenv("DIGESTIF_TLPDB")
  if DIGESTIF_TLPDB then
    config.tlpdb_path = util.path_list_split(DIGESTIF_TLPDB)
  end
end

function config.check_data(dir)
  if not dir then
    for _, dir in ipairs(config.data_dirs) do
      if config.check_data(dir) then return true end
    end
  end
  local f = io.open(util.path_join(dir, "primitives.tags"))
  if f then
    f:close()
    return true
  end
end

return config