1# compdef setxkbmap
2
3# TODO:
4# model, option, symbols and types suggestions
5# take -layout and -variant into account
6
7_setxkbmap() {
8    emulate -L zsh
9    setopt extendedglob
10
11    # xkb files may be in different places depending on system
12    local dir sourcedir
13    for dir in /usr/lib/X11/xkb /usr/share/X11/xkb; do
14        if [ -d $dir ] ; then
15           sourcedir=$dir
16           break
17        fi
18    done
19    [ -d $sourcedir ] || return 1
20
21    local -a arguments
22
23    arguments=(
24        '-compat[compability map]:compability:_setxkbmap_compat'
25        '-config[configuration file]:configuration:_files'
26        '-display[display]:display:_x_display'
27        '-geometry[geometry component]:geometry:_setxkbmap_geometry'
28        '-model[model name]:model:'
29        '-option[xkb option]:option:'
30        '(-)'-print'[print component names]'
31        '-rules[rules file]:rules:_files'
32        '-symbols[symbols components]:symbols:'
33        '(-)'{-help,-h}'[display help message]'
34        '-synch[force synchronization]'
35        '-types[types components]:types:'
36        '(-verbose -v)'{-verbose,-v}'[set verbosity level]:verbosity:(0 1 2 3 4 5 6 7 8 9)'
37        '*::keyboard:_setxkbmap_dispatcher'
38    )
39    _arguments $arguments
40}
41
42_setxkbmap_dispatcher () {
43
44    case $CURRENT in
45        1)
46            _setxkbmap_layout
47        ;;
48        2)
49            _setxkbmap_variant "$words[1]"
50        ;;
51    esac
52}
53
54_setxkbmap_files () {
55    local dir="$1"
56    local label="$2"
57
58    local -a fullpath shortpath
59
60    fullpath=($sourcedir/$dir/**/*~*README(.))
61    shortpath=(${fullpath#$sourcedir\/$dir\/})
62
63    _wanted layout expl $label compadd -a - shortpath
64
65}
66
67(( $+functions[_setxkbmap_compat] )) ||
68_setxkbmap_compat() {
69    _setxkbmap_files "compat" "compatibility"
70}
71
72(( $+functions[_setxkbmap_layout] )) ||
73_setxkbmap_layout () {
74    _setxkbmap_files "symbols" "layout"
75}
76
77(( $+functions[_setxkbmap_geometry] )) ||
78_setxkbmap_geometry () {
79    _setxkbmap_files "geometry" "geometry"
80}
81
82(( $+functions[_setxkbmap_variant] )) ||
83_setxkbmap_variant () {
84    local file=$sourcedir/symbols/${1}
85    local -a variants lines
86
87    if [ ! -f $file ]; then
88        _message "no such layout: ${1}"
89        return 1
90    fi
91
92    lines=("${(f)$(< ${file})}")
93    variants=(${${${(M)lines:#*xkb_symbols*\"([[:alnum:]])##\"*}##*xkb_symbols([^\"])##\"}%%\"*})
94    
95    _wanted variant expl 'variant' compadd -a variants
96
97}
98
99_setxkbmap "$@"
100