@@ -105,6 +105,8 @@ buffer-local wherever it is set."
105105(declare-function pkg-info-version-info " pkg-info" (library))
106106
107107(eval-when-compile
108+ (require 'cl-macs )
109+ (require 'skeleton )
108110 (require 'rx ))
109111
110112(require 'align )
@@ -1127,6 +1129,189 @@ With a prefix argument SUPPRESS it simply inserts $."
11271129 (delete-region (+ min 1 ) (- max 1 )))))
11281130
11291131
1132+
1133+ ; ;; Skeletons
1134+
1135+ (defun puppet-dissect-filename (file )
1136+ " Return list of path components for the Puppet manifest FILE.
1137+ The first element of the list will be the module name and the
1138+ remaining elements are the relative path components below the
1139+ ‘manifests’ subdirectory. The names of the path components are
1140+ only derived from the file name by using the Puppet auto-loader
1141+ rules. FILE must be an absolute file name.
1142+
1143+ The module name \" unidentified\" is returned if a module name
1144+ can't be inferred from the file name.
1145+
1146+ If the directory name contains characters that are not legal for
1147+ a Puppet module name, then all leading characters including the
1148+ last illegal character are removed from the module name. The
1149+ function will for example return ‘foo’ as module name even if the
1150+ module is using the ‘puppet-foo’ directory (e.g. for module
1151+ development in a user's home directory)."
1152+ (if (stringp file)
1153+ (let* ((parts (cl-loop for path = file then (directory-file-name
1154+ (file-name-directory path))
1155+ ; ; stop iteration at the root of the directory
1156+ ; ; tree (should work for Windows & Unix/Linux)
1157+ until (or (string-suffix-p " :" path)
1158+ (string-equal (file-name-directory path)
1159+ path))
1160+ collect (file-name-base path)))
1161+ ; ; Remove "init" if it is the first element
1162+ (compact (if (string-equal (car parts) " init" )
1163+ (cdr parts)
1164+ parts)))
1165+ (cons
1166+ ; ; module name with illegal prefixes removed or "unidentified" if
1167+ ; ; path is not compliant with the standard Puppet file hierarchy
1168+ (replace-regexp-in-string
1169+ " ^.*[^a-z0-9_]" " " (or (cadr (member " manifests" parts))
1170+ " unidentified" ))
1171+ ; ; remaining path components
1172+ (cdr (member " manifests" (reverse compact)))))
1173+ '(" unidentified" )))
1174+
1175+ (defun puppet-file-module-name (file )
1176+ " Return the module name for the Puppet class in FILE."
1177+ (car (puppet-dissect-filename file)))
1178+
1179+ (defun puppet-file-class-name (file )
1180+ " Return the class name for the Puppet class in FILE."
1181+ (mapconcat #'identity (puppet-dissect-filename file) " ::" ))
1182+
1183+ (define-skeleton puppet-keyword-class
1184+ " Insert \" class\" skeleton."
1185+ nil
1186+ " class " (puppet-file-class-name (buffer-file-name )) " (" > \n
1187+ " ) {" > \n
1188+ > _ " }" > \n )
1189+
1190+ (define-skeleton puppet-keyword-define
1191+ " Insert \" class\" skeleton."
1192+ nil
1193+ " define " (puppet-file-class-name (buffer-file-name )) " (" > \n
1194+ " ) {" > \n
1195+ > _ " }" > \n )
1196+
1197+ (define-skeleton puppet-keyword-node
1198+ " Insert \" node\" skeleton."
1199+ nil
1200+ " node " > - " {" \n
1201+ > _ " }" > \n )
1202+
1203+ (define-skeleton puppet-keyword-if
1204+ " Insert \" if\" statement."
1205+ nil
1206+ " if " > - " {" \n
1207+ > _ " }" > \n )
1208+
1209+ (define-skeleton puppet-keyword-elsif
1210+ " Insert \" elsif\" statement."
1211+ nil
1212+ " elsif " > - " {" \n
1213+ > _ " }" > \n )
1214+
1215+ (define-skeleton puppet-keyword-else
1216+ " Insert \" else\" statement."
1217+ nil
1218+ " else {" > \n
1219+ > _ " }" > \n )
1220+
1221+ (define-skeleton puppet-keyword-unless
1222+ " Insert \" unless\" statement."
1223+ nil
1224+ " unless " > - " {" \n
1225+ > _ " }" > \n )
1226+
1227+ (define-skeleton puppet-keyword-case
1228+ " Insert \" case\" statement."
1229+ nil
1230+ " case " > - " {" \n
1231+ " default: {" > \n
1232+ " }" > \n
1233+ " }" > \n )
1234+
1235+ (define-skeleton puppet-keyword-selector
1236+ " Insert \" ?\" selector."
1237+ nil
1238+ " ? {" > \n
1239+ " default => " > - " ," \n
1240+ " }" > \n )
1241+
1242+ (define-skeleton puppet-type-anchor
1243+ " Insert the \" anchor\" resource type."
1244+ nil
1245+ " anchor { " > - " : }" \n )
1246+
1247+ (define-skeleton puppet-type-class
1248+ " Insert the \" class\" resource type."
1249+ nil
1250+ " class { " > - " :" \n
1251+ " }" > \n )
1252+
1253+ (define-skeleton puppet-type-exec
1254+ " Insert the \" exec\" resource type."
1255+ nil
1256+ " exec { " > - " :" \n
1257+ " path => [ '/bin', '/sbin', '/usr/bin', '/usr/sbin', ]," > \n
1258+ " user => 'root'," > \n
1259+ " cwd => '/'," > \n
1260+ " }" > \n )
1261+
1262+ (define-skeleton puppet-type-file
1263+ " Insert the \" file\" resource type."
1264+ nil
1265+ " file { " > - " :" \n
1266+ " ensure => file," > \n
1267+ " owner => 'root'," > \n
1268+ " group => 'root'," > \n
1269+ " mode => '0644'," > \n
1270+ " }" > \n )
1271+
1272+ (define-skeleton puppet-type-group
1273+ " Insert the \" group\" resource type."
1274+ nil
1275+ " group { " > - " :" \n
1276+ " ensure => present," > \n
1277+ " }" > \n )
1278+
1279+ (define-skeleton puppet-type-host
1280+ " Insert the \" host\" resource type."
1281+ nil
1282+ " host { " > - " :" \n
1283+ " ensure => present," > \n
1284+ " }" > \n )
1285+
1286+ (define-skeleton puppet-type-notify
1287+ " Insert the \" notify\" resource type."
1288+ nil
1289+ " notify { " > - " : }" \n )
1290+
1291+ (define-skeleton puppet-type-package
1292+ " Insert the \" package\" resource type."
1293+ nil
1294+ " package { " > - " :" \n
1295+ " ensure => present," > \n
1296+ " }" > \n )
1297+
1298+ (define-skeleton puppet-type-service
1299+ " Insert the \" service\" resource type."
1300+ nil
1301+ " service { " > - " :" \n
1302+ " ensure => running," > \n
1303+ " enable => true," > \n
1304+ " }" > \n )
1305+
1306+ (define-skeleton puppet-type-user
1307+ " Insert the \" user\" resource type."
1308+ nil
1309+ " user { " > - " :" \n
1310+ " ensure => present," > \n
1311+ " shell => '/bin/bash'," > \n
1312+ " password => '*'," > \n
1313+ " }" > \n )
1314+
11301315
11311316; ;; Imenu
11321317
@@ -1220,6 +1405,27 @@ for each entry."
12201405 ; ; Linting and validation
12211406 (define-key map (kbd " C-c C-v" ) #'puppet-validate )
12221407 (define-key map (kbd " C-c C-l" ) #'puppet-lint )
1408+ ; ; Skeletons for types
1409+ (define-key map (kbd " C-c C-t a" ) #'puppet-type-anchor )
1410+ (define-key map (kbd " C-c C-t c" ) #'puppet-type-class )
1411+ (define-key map (kbd " C-c C-t e" ) #'puppet-type-exec )
1412+ (define-key map (kbd " C-c C-t f" ) #'puppet-type-file )
1413+ (define-key map (kbd " C-c C-t g" ) #'puppet-type-group )
1414+ (define-key map (kbd " C-c C-t h" ) #'puppet-type-host )
1415+ (define-key map (kbd " C-c C-t n" ) #'puppet-type-notify )
1416+ (define-key map (kbd " C-c C-t p" ) #'puppet-type-package )
1417+ (define-key map (kbd " C-c C-t s" ) #'puppet-type-service )
1418+ (define-key map (kbd " C-c C-t u" ) #'puppet-type-user )
1419+ ; ; Skeletons for keywords
1420+ (define-key map (kbd " C-c C-k c" ) #'puppet-keyword-class )
1421+ (define-key map (kbd " C-c C-k d" ) #'puppet-keyword-define )
1422+ (define-key map (kbd " C-c C-k n" ) #'puppet-keyword-node )
1423+ (define-key map (kbd " C-c C-k i" ) #'puppet-keyword-if )
1424+ (define-key map (kbd " C-c C-k e" ) #'puppet-keyword-elsif )
1425+ (define-key map (kbd " C-c C-k o" ) #'puppet-keyword-else )
1426+ (define-key map (kbd " C-c C-k u" ) #'puppet-keyword-unless )
1427+ (define-key map (kbd " C-c C-k s" ) #'puppet-keyword-case )
1428+ (define-key map (kbd " C-c C-k ?" ) #'puppet-keyword-selector )
12231429 ; ; The menu bar
12241430 (easy-menu-define puppet-menu map " Puppet Mode menu"
12251431 `(" Puppet"
@@ -1278,6 +1484,8 @@ for each entry."
12781484 ; ; Alignment
12791485 (setq align-mode-rules-list puppet-mode-align-rules)
12801486 (setq align-mode-exclude-rules-list puppet-mode-align-exclude-rules)
1487+ ; ; Skeletons
1488+ (setq-local skeleton-end-newline nil )
12811489 ; ; IMenu
12821490 (setq imenu-create-index-function #'puppet-imenu-create-index ))
12831491
0 commit comments