~yerinalexey/miniplug

ref: 6342552d7da44126e1bf1bac5cbeb9f35299ef7e miniplug/miniplug.zsh -rw-r--r-- 4.8 KiB
6342552d — Alexey Yerin Do not source plugin if it was already sourced 1 year, 3 months ago
                                                                                
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/usr/bin/env zsh

# Miniplug - minimalistic plugin manager for ZSH

# Globals
declare MINIPLUG_HOME="${MINIPLUG_HOME:-$HOME/.miniplug}"
declare MINIPLUG_THEME="${MINIPLUG_THEME:-}"
declare MINIPLUG_PLUGINS=()

[ -z "$MINIPLUG_LOADED_PLUGINS" ] && declare MINIPLUG_LOADED_PLUGINS=()

# Helper functions {{{
# Friendly wrapper around find
function __miniplug_find() {
  local searchdir="$1"
  local searchterm="$2"

  find "$searchdir" -maxdepth 1 -type f -name "$searchterm"
}

# Check if plugin is already loaded
function __miniplug_check_loaded() {
  local target_plugin="$1" plugin_url

  for plugin_url in ${MINIPLUG_LOADED_PLUGINS[*]}; do
    [ "$target_plugin" = "$plugin_url" ] && return
  done

  return 1
}
# }}}

# Core functions {{{
# Show help message
function __miniplug_usage() {
  echo "Miniplug - minimalistic plugin manager for ZSH"
  echo "Usage: miniplug <command> [arguments]"
  echo "Commands:"
  echo "  plugin <source> - Register a plugin"
  echo "  theme <source> - Register a theme (can be done only once)"
  echo "  install - Install plugins"
  echo "  help - Show this message"
  echo "About <source>:"
  echo "  <source> can be either full URL to Git repository or Github's user/repo"
  echo "  Examples: https://gitlab.com/user/repo, zsh-users/repo (expanded to https://github.com/zsh-users/repo)"
}

# Register a plugin
function __miniplug_plugin() {
  local plugin_url="$1"

  MINIPLUG_PLUGINS+=("$plugin_url")
}

# Register a theme
function __miniplug_theme() {
  local theme_url="$1"

  # Throw an error if theme is already set but not if MINIPLUG_THEME and new theme match
  if [ -n "$MINIPLUG_THEME" ] && [ "$MINIPLUG_THEME" != "$theme_url" ]; then
    echo "Theme is already set"
    return 1
  fi

  MINIPLUG_PLUGINS+=("$theme_url")
  MINIPLUG_THEME="$theme_url"
}

# Install plugins
function __miniplug_install() {
  local plugin_url plugin_name clone_url clone_dest

  # Make sure MINIPLUG_HOME exists
  mkdir -p "$MINIPLUG_HOME"

  for plugin_url in ${MINIPLUG_PLUGINS[*]}; do
    # Get plugin name (last two URL segments)
    plugin_name="$(echo "$plugin_url" | awk -F '/' '{ print $(NF - 1) "/" $NF }')"

    # Get URL for git clone
    clone_url="$(echo "$plugin_url" | awk -F '/' '{
      if (match($0, /^https:\/\//)) {
        print $0
      } else {
        print "https://github.com/" $0
      }
    }')"

    # Where to clone this plugin
    clone_dest="$MINIPLUG_HOME/$plugin_name"

    # Check if plugin is already installed
    if [ -d "$clone_dest" ]; then
      echo "$plugin_url is already installed, skipping"
      continue
    fi

    # Clone
    echo "Installing $plugin_url ..."
    git clone "$clone_url" "$clone_dest" -q || (
      echo "Failed to install $plugin_url, exiting"
      return 1
    )
  done
}

# Load plugins
function __miniplug_load() {
  local plugin_url plugin_name plugin_location source_zsh_plugin source_dotzsh source_zsh_theme

  # Make sure MINIPLUG_HOME exists
  mkdir -p "$MINIPLUG_HOME"

  for plugin_url in ${MINIPLUG_PLUGINS[*]}; do
    # Get plugin name (last two URL segments)
    plugin_name="$(echo "$plugin_url" | awk -F '/' '{ print $(NF - 1) "/" $NF }')"

    # Where this plugin is located
    plugin_location="$MINIPLUG_HOME/$plugin_name"

    # Check if plugin is installed
    if [ ! -d "$plugin_location" ]; then
      echo "$plugin_url is not installed, run 'miniplug install' to install it"
      continue
    fi

    # Check if plugin is already loaded
    __miniplug_check_loaded "$plugin_url" && continue

    # 1st source - .plugin.zsh file
    source_zsh_plugin="$(__miniplug_find "$plugin_location" "*.plugin.zsh")"

    if [ -n "$source_zsh_plugin" ]; then
      source "$source_zsh_plugin"
      MINIPLUG_LOADED_PLUGINS+=("$plugin_url")

      continue
    fi

    # 2nd source - .zsh file
    source_dotzsh="$(__miniplug_find "$plugin_location" "*.zsh")"

    if [ -n "$source_dotzsh" ]; then
      source "$source_dotzsh"
      MINIPLUG_LOADED_PLUGINS+=("$plugin_url")

      continue
    fi

    # 3rd source - .zsh-theme file (only for themes)
    if [ "$MINIPLUG_THEME" = "$plugin_url" ]; then
      source_zsh_theme="$(__miniplug_find "$plugin_location" "*.zsh-theme")"

      if [ -n "$source_zsh_theme" ]; then
        source "$source_zsh_theme"
        MINIPLUG_LOADED_PLUGINS+=("$plugin_url")

        continue
      fi
    fi

    # If none of sources has been found
    if [ "$MINIPLUG_THEME" = "$plugin_url" ]; then
      echo "No .zsh-theme, .plugin.zsh or .zsh file found, most likely, $plugin_url is not a valid ZSH theme"
    else
      echo "No .plugin.zsh or .zsh file found, most likely, $plugin_url is not a valid ZSH plugin"
    fi
  done
}
# }}}

# Wrapper command for core functions
function miniplug() {
  case "$1" in
    plugin) __miniplug_plugin "$2" ;;
    theme) __miniplug_theme "$2" ;;
    install) __miniplug_install ;;
    load) __miniplug_load ;;
    help) __miniplug_usage ;;
    *) __miniplug_usage ;;
  esac
}