This file is indexed.

/usr/share/bibus/LyX/bindings.py is in bibus 1.5.2-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
157
158
159
160
161
# bindings.py                    -*- coding: iso-8859-1 -*-
# Copyright (c) 2005 Günter Milde
# Released under the terms of the GNU General Public License (ver. 2 or later)

"""
A dictionary of LyX keybindings

Scans recursively for `\bind_file`s and stores keybindings in a dictionary
`bindings`. Starts with the preferences file `rcfile`.

Uses the following defaults from LyX.constants.py
   SYSTEM_DIR, USER_DIR, LYXRC_FILE
Change this variables in `~/.lyx/scripts/python/config.py`, if your settings differ

Doesnot currently 'normalize' the keynames, i.e. if different spellings for 
the same key occure in different bind-files, both bindings will be reported.
(Normally, the latter binding will overwrite the first one, get_bindings()
will only overwrite bindings with equal spelling.)

TODO: emulate the keyname 'normalization'
"""

import os, sys, logging, re
from LyX import __path__

# Customizable values
from constants import SYSTEM_DIR, USER_DIR, LYXRC_FILE, LOG_LEVEL

# set up the logger instance
logger = logging.getLogger("bindings")
logging.basicConfig()
#set verbosity to show all messages of severity >= LOG_LEVEL
logger.setLevel(LOG_LEVEL) 

# debugging
# logger.setLevel(logging.DEBUG)

def bindfile_path(filename):
    """Return the full path for the bind file `filename`
    
    Return empty string, if file is not found.
    
    Like the LyX binary, this looks first in USER_DIR and then in SYSTEM_DIR
    """
    # Add default extension ('.bind') if no extension is given
    ext = os.path.splitext(filename)[1]
    if not ext:
        filename += '.bind'
    for base_path in (USER_DIR, SYSTEM_DIR):
        path = os.path.join(base_path, 'bind', filename)
        if os.path.isfile(path):
            return path
    logger.warning("bind-file %s not found in %s or %s"%
                   (filename, USER_DIR, SYSTEM_DIR))
    return ''


def get_bindings(path=LYXRC_FILE):
    """Return a list of bindfiles and a dictionary of keybindings.
    
    Scan `path` recursively for `\bind_file`s, return
    
      * a list of included bind-files, and
      * a "keyname: binding" dictionary of key-bindings
    """
    # if not path: 
    #     return {}
    bindings = {}
    bindfiles = []
    if path != LYXRC_FILE:
        path = bindfile_path(path)
    logger.debug(" scanning '%s'"%path)
    for line in file(path):
        # logger.debug(" get_bindigs: parsing %s"%line.strip)
        if line.startswith(r'\bind_file'):
            (command, bindfile) = line.split(None, 1)
            bindfile = bindfile_path(bindfile.strip())
            if bindfile:
                bindfiles.append(bindfile)
                bf, kb = get_bindings(bindfile)
                bindfiles += bf
                bindings.update(kb)
        elif line.startswith(r'\bind'):
            (command, key, binding) = line.split('"', 2)
            bindings[key] = binding.strip()
    return bindfiles, bindings


# extended Help functions (do not need a running LyX)
# ---------------------------------------------------


def apropos(pattern, path="doc/lfuns.txt"):
    """re.search for `pattern` in text file `path`, return list of matches
    
    A non-absolute pathname will be expanded relative to the packages
    __path__.
    
    Together with the file lfuns.txt in the doc subdir, this is a hack to get
    a behaviour similar to JEDs apropos(), i.e. return a list of 
    lyx-functions matching `pattern`.
    """
    # get the description file
    for root in  __path__ + [""]:
        try:
            fp = file(os.path.join(root, path))
            break
        except IOError:
            pass
    # filter relevant lines
    pattern_re = re.compile(pattern)
    return [line for line in fp if pattern_re.search(line)]


def where_is(lfun, path=LYXRC_FILE):
    """Return dictionary with the key(s) `lfun` is bound to
    
    Does a regexp search for `lfun` in the keybindings dictionary values
    """
    lfun_re = re.compile(lfun)
    bindings = {}
    for key, value in get_bindings(path)[1].iteritems():
        if lfun_re.search(value):
            bindings[key] = value
    return bindings


def showkey(key, path=LYXRC_FILE):
    """Return lfun bound to `key`
    
    Doesnot currently 'normalize' the keynames, i.e. only works for 
    keynames as found in the *.bind files
    """
    try:
        return get_bindings(path)[1][key]
    except KeyError:
        return "Key %s undefined (maybe different spelling?)"%key


def print_bindings(bindings, verbose=False):
    """Pretty print the keybindings dictionary with adjusted columns and
    TAB separated keyname and function (to facilitate reading as CSV data)
    """
    if not bindings:
        print "no bindings"
        return
    keys = bindings.keys()
    keys.sort()
    # sort case insensitive
    # tmplist = [(key.lower(), key) for key in keys]
    # tmplist.sort()
    # keys = [key for (lowkey, key) in tmplist]
    max_keylen = max(map(len, keys))
    for key in keys:
        if verbose or (bindings[key] != '"self-insert"'):
            print "%s\t%s"%(key.ljust(max_keylen), bindings[key])

# ---------------------------------------------------------------------------

if __name__ == '__main__':
    print_bindings(get_bindings()[1])