Codebase list emacs-powerline / upstream/2.4 powerline-separators.el
upstream/2.4

Tree @upstream/2.4 (Download .tar.gz)

powerline-separators.el @upstream/2.4raw · history · blame

  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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
;;; powerline-separators.el --- Separators for Powerline

;; Copyright (C) 2012-2013 Donald Ephraim Curtis
;; Copyright (C) 2013 Jason Milkins
;; Copyright (C) 2012 Nicolas Rougier

;;; Commentary:
;;
;; Separators for Powerline.
;; Included separators: alternate, arrow, arrow-fade, bar, box, brace, butt,
;; chamfer, contour, curve, rounded, roundstub, slant, wave, zigzag, and nil.
;;

;;; Code:

(require 'cl-lib)
(require 'color)

(defun pl/interpolate (color1 color2)
  "Interpolate between COLOR1 and COLOR2.

COLOR1 and COLOR2 must be supplied as hex strings with a leading #."
  (let* ((c1 (color-name-to-rgb color1))
         (c2 (color-name-to-rgb color2))
         (red (/ (+ (nth 0 c1) (nth 0 c2)) 2))
         (green (/ (+ (nth 1 c1) (nth 1 c2)) 2))
         (blue (/ (+ (nth 2 c1) (nth 2 c2)) 2)))
    (color-rgb-to-hex red green blue)))

(defun pl/hex-color (color)
  "Get the hexadecimal value of COLOR."
  (when color
    (apply 'color-rgb-to-hex (color-name-to-rgb color))))

(defun pl/pattern (lst)
  "Turn LST into an infinite pattern."
  (when lst
    (let ((pattern (cl-copy-list lst)))
      (setcdr (last pattern) pattern))))

(defun pl/pattern-to-string (pattern)
  "Convert a PATTERN into a string that can be used in an XPM."
  (concat "\"" (mapconcat 'number-to-string pattern "") "\","))

(defun pl/reverse-pattern (pattern)
  "Reverse each line in PATTERN."
  (mapcar 'reverse pattern))

(defun pl/row-pattern (fill total &optional fade)
  "Make a list that has FILL 0s out of TOTAL 1s with FADE 2s to the right of the fill."
  (unless fade
    (setq fade 0))
  (let ((fill (min fill total))
        (fade (min fade (max (- total fill) 0))))
    (append (make-list fill 0)
            (make-list fade 2)
            (make-list (- total fill fade) 1))))

(defun pl/pattern-bindings-body (patterns height-exp pattern-height-sym
					  second-pattern-height-sym)
  "Create let-var bindings and a function body from PATTERNS.
The `car' and `cdr' parts of the result can be passed to the
function `pl/wrap-defun' as its `let-vars' and `body' arguments,
respectively.  HEIGHT-EXP is an expression calculating the image
height and it should contain a free variable `height'.
PATTERN-HEIGHT-SYM and SECOND-PATTERN-HEIGHT-SYM are symbols used
for let-var binding variables."
  (let* ((pattern (pl/pattern (mapcar 'pl/pattern-to-string (car patterns))))
         (header (mapcar 'pl/pattern-to-string (nth 1 patterns)))
         (footer (mapcar 'pl/pattern-to-string (nth 2 patterns)))
         (second-pattern (pl/pattern (mapcar 'pl/pattern-to-string (nth 3 patterns))))
         (center (mapcar 'pl/pattern-to-string (nth 4 patterns)))
         (reserve (+ (length header) (length footer) (length center))))
    (when pattern
      (cons `((,pattern-height-sym (max (- ,height-exp ,reserve) 0))
	      (,second-pattern-height-sym (/ ,pattern-height-sym 2))
	      (,pattern-height-sym ,(if second-pattern `(ceiling ,pattern-height-sym 2) `,pattern-height-sym)))
	    (list (when header `(mapconcat 'identity ',header ""))
		  `(mapconcat 'identity
			      (cl-subseq ',pattern 0 ,pattern-height-sym) "")
		  (when center `(mapconcat 'identity ',center ""))
		  (when second-pattern
		    `(mapconcat 'identity
				(cl-subseq ',second-pattern
					   0 ,second-pattern-height-sym) ""))
		  (when footer `(mapconcat 'identity ',footer "")))))))

(defun pl/pattern-defun (name dir width &rest patterns)
  "Create a powerline function of NAME in DIR with WIDTH for PATTERNS.

PATTERNS is of the form (PATTERN HEADER FOOTER SECOND-PATTERN CENTER
PATTERN-2X HEADER-2X FOOTER-2X SECOND-PATTERN-2X CENTER-2X).
PATTERN is required, all other components are optional.
The first 5 components are for the standard resolution image.
The remaining ones are for the high resolution image where both
width and height are doubled.  If PATTERN-2X is nil or not given,
then the remaining components are ignored and the standard
resolution image with magnification and interpolation will be
used in high resolution environments

All generated functions generate the form:
HEADER
PATTERN ...
CENTER
SECOND-PATTERN ...
FOOTER

PATTERN and SECOND-PATTERN repeat infinitely to fill the space needed to generate a full height XPM.

PATTERN, HEADER, FOOTER, SECOND-PATTERN, CENTER are of the form ((COLOR ...) (COLOR ...) ...).

COLOR can be one of 0, 1, or 2, where 0 is the source color, 1 is the
destination color, and 2 is the interpolated color between 0 and 1."
  (when (eq dir 'right)
    (setq patterns (mapcar 'pl/reverse-pattern patterns)))
  (let ((bindings-body (pl/pattern-bindings-body patterns
						 'height
						 'pattern-height
						 'second-pattern-height))
	(bindings-body-2x (pl/pattern-bindings-body (nthcdr 5 patterns)
						    '(* height 2)
						    'pattern-height-2x
						    'second-pattern-height-2x)))
    (pl/wrap-defun name dir width
		   (append (car bindings-body) (car bindings-body-2x))
		   (cdr bindings-body) (cdr bindings-body-2x))))

(defun pl/background-color (face)
  (face-attribute face
                  (if (face-attribute face :inverse-video nil 'default)
                      :foreground
                    :background)
                  nil
                  'default))

(defun pl/wrap-defun (name dir width let-vars body &optional body-2x)
  "Generate a powerline function of NAME in DIR with WIDTH using LET-VARS and BODY."
  (let* ((src-face (if (eq dir 'left) 'face1 'face2))
         (dst-face (if (eq dir 'left) 'face2 'face1)))
    `(defun ,(intern (format "powerline-%s-%s" name (symbol-name dir)))
       (face1 face2 &optional height)
       (when window-system
         (unless height (setq height (pl/separator-height)))
         (let* ,(append `((color1 (when ,src-face
                                    (pl/hex-color (pl/background-color ,src-face))))
                          (color2 (when ,dst-face
                                    (pl/hex-color (pl/background-color ,dst-face))))
                          (colori (when (and color1 color2) (pl/interpolate color1 color2)))
                          (color1 (or color1 "None"))
                          (color2 (or color2 "None"))
                          (colori (or colori "None")))
                        let-vars)
           (apply 'create-image
		  ,(append `(concat (format "/* XPM */ static char * %s_%s[] = { \"%s %s 3 1\", \"0 c %s\", \"1 c %s\", \"2 c %s\","
					    ,(replace-regexp-in-string "-" "_" name)
					    (symbol-name ',dir)
					    ,width
					    height
					    color1
					    color2
					    colori))
			   body
			   '("};"))
		  'xpm t
		  :ascent 'center
		  :face (when (and face1 face2)
			  ,dst-face)
		  ,(and body-2x
			`(and (featurep 'mac)
			      (list :data-2x
				    ,(append `(concat (format "/* XPM */ static char * %s_%s_2x[] = { \"%s %s 3 1\", \"0 c %s\", \"1 c %s\", \"2 c %s\","
							      ,(replace-regexp-in-string "-" "_" name)
							      (symbol-name ',dir)
							      (* ,width 2)
							      (* height 2)
							      color1
							      color2
							      colori))
					     body-2x
					     '("};")))))))))))

(defmacro pl/alternate (dir)
  "Generate an alternating pattern XPM function for DIR."
  (pl/pattern-defun "alternate" dir 4
                    '((2 2 1 1)
                      (0 0 2 2))
		    nil nil nil nil
		    ;; 2x
		    '((2 2 2 2 1 1 1 1)
		      (2 2 2 2 1 1 1 1)
		      (0 0 0 0 2 2 2 2)
		      (0 0 0 0 2 2 2 2))))

(defmacro pl/arrow (dir)
  "Generate an arrow XPM function for DIR."
  (let ((row-modifier (if (eq dir 'left) 'identity 'reverse)))
    (pl/wrap-defun "arrow" dir 'middle-width
                   '((width (1- (/ height 2)))
                     (middle-width (1- (ceiling height 2))))
                   `((cl-loop for i from 0 to width
                              concat (pl/pattern-to-string (,row-modifier (pl/row-pattern i middle-width))))
                     (when (cl-oddp height)
                       (pl/pattern-to-string (make-list middle-width 0)))
                     (cl-loop for i from width downto 0
                              concat (pl/pattern-to-string (,row-modifier (pl/row-pattern i middle-width)))))
		   `((when (cl-evenp height)
                       (pl/pattern-to-string (make-list (* middle-width 2) 1)))
		     (cl-loop for i from 0 to (* middle-width 2)
                              concat (pl/pattern-to-string (,row-modifier (pl/row-pattern i (* middle-width 2)))))
                     (cl-loop for i from (* middle-width 2) downto 0
                              concat (pl/pattern-to-string (,row-modifier (pl/row-pattern i (* middle-width 2)))))
		     (when (cl-evenp height)
                       (pl/pattern-to-string (make-list (* middle-width 2) 1)))))))

(defmacro pl/arrow-fade (dir)
  "Generate an arrow-fade XPM function for DIR."
  (let* ((row-modifier (if (eq dir 'left) 'identity 'reverse)))
    (pl/wrap-defun "arrow-fade" dir 'middle-width
                   '((width (1- (/ height 2)))
                     (middle-width (1+ (ceiling height 2))))
                   `((cl-loop for i from 0 to width
                              concat (pl/pattern-to-string (,row-modifier (pl/row-pattern i middle-width 2))))
                     (when (cl-oddp height)
                       (pl/pattern-to-string (,row-modifier (pl/row-pattern (1+ width) middle-width 2))))
                     (cl-loop for i from width downto 0
                              concat (pl/pattern-to-string (,row-modifier (pl/row-pattern i middle-width 2)))))
		   `((when (cl-evenp height)
                       (pl/pattern-to-string (,row-modifier (pl/row-pattern 0 (* middle-width 2) (* 2 2)))))
		     (cl-loop for i from 0 to (* (- middle-width 2) 2)
                              concat (pl/pattern-to-string (,row-modifier (pl/row-pattern i (* middle-width 2) (* 2 2)))))
                     (cl-loop for i from (* (- middle-width 2) 2) downto 0
                              concat (pl/pattern-to-string (,row-modifier (pl/row-pattern i (* middle-width 2) (* 2 2)))))
		     (when (cl-evenp height)
                       (pl/pattern-to-string (,row-modifier (pl/row-pattern 0 (* middle-width 2) (* 2 2)))))))))

(defmacro pl/bar (dir)
  "Generate a bar XPM function for DIR."
  (pl/pattern-defun "bar" dir 2
                    '((2 2))))

(defmacro pl/box (dir)
  "Generate a box XPM function for DIR."
  (pl/pattern-defun "box" dir 2
                    '((0 0)
                      (0 0)
                      (1 1)
                      (1 1))
		    nil nil nil nil
		    ;; 2x
		    '((0 0 0 0)
		      (0 0 0 0)
		      (0 0 0 0)
		      (0 0 0 0)
		      (1 1 1 1)
		      (1 1 1 1)
		      (1 1 1 1)
		      (1 1 1 1))))

(defmacro pl/brace (dir)
  "Generate a brace XPM function for DIR."
  (pl/pattern-defun "brace" dir 4
                    '((0 1 1 1))
                    '((1 1 1 1)
                      (2 1 1 1))
                    '((2 1 1 1)
                      (1 1 1 1))
                    '((0 1 1 1))
                    '((0 2 1 1)
                      (0 2 1 1)
                      (0 0 2 1)
                      (0 0 0 0)
                      (0 0 2 1)
                      (0 2 1 1)
                      (0 2 1 1))
		    ;; 2x
		    '((0 0 1 1 1 1 1 1))
		    '((1 1 1 1 1 1 1 1)
		      (1 1 1 1 1 1 1 1)
		      (2 1 1 1 1 1 1 1)
		      (0 2 1 1 1 1 1 1))
		    '((0 2 1 1 1 1 1 1)
		      (2 1 1 1 1 1 1 1)
		      (1 1 1 1 1 1 1 1)
		      (1 1 1 1 1 1 1 1))
		    '((0 0 1 1 1 1 1 1))
		    '((0 0 2 1 1 1 1 1)
		      (0 0 0 1 1 1 1 1)
		      (0 0 0 2 1 1 1 1)
		      (0 0 0 0 1 1 1 1)
		      (0 0 0 0 2 1 1 1)
		      (0 0 0 0 0 2 1 1)
		      (0 0 0 0 0 0 0 2)
		      (0 0 0 0 0 0 0 2)
		      (0 0 0 0 0 2 1 1)
		      (0 0 0 0 2 1 1 1)
		      (0 0 0 0 1 1 1 1)
		      (0 0 0 2 1 1 1 1)
		      (0 0 0 1 1 1 1 1)
		      (0 0 2 1 1 1 1 1))))

(defmacro pl/butt (dir)
  "Generate a butt XPM function for DIR."
  (pl/pattern-defun "butt" dir 3
                    '((0 0 0))
                    '((1 1 1)
                      (0 1 1)
                      (0 0 1))
                    '((0 0 1)
                      (0 1 1)
                      (1 1 1))
		    nil nil
		    ;; 2x
		    '((0 0 0 0 0 0))
		    '((1 1 1 1 1 1)
		      (0 1 1 1 1 1)
		      (0 0 1 1 1 1)
		      (0 0 0 1 1 1)
		      (0 0 0 0 1 1)
		      (0 0 0 0 0 1))
		    '((0 0 0 0 0 1)
		      (0 0 0 0 1 1)
		      (0 0 0 1 1 1)
		      (0 0 1 1 1 1)
		      (0 1 1 1 1 1)
		      (1 1 1 1 1 1))))

(defmacro pl/chamfer (dir)
  "Generate a chamfer XPM function for DIR."
  (pl/pattern-defun "chamfer" dir 3
                    '((0 0 0))
                    '((1 1 1)
                      (0 1 1)
                      (0 0 1))
		    nil nil nil
		    ;; 2x
		    '((0 0 0 0 0 0))
		    '((1 1 1 1 1 1)
		      (0 1 1 1 1 1)
		      (0 0 1 1 1 1)
		      (0 0 0 1 1 1)
		      (0 0 0 0 1 1)
		      (0 0 0 0 0 1))))

(defmacro pl/contour (dir)
  "Generate a contour XPM function for DIR."
  (pl/pattern-defun "contour" dir 10
                    '((0 0 0 0 0 1 1 1 1 1))
                    '((1 1 1 1 1 1 1 1 1 1)
                      (0 2 1 1 1 1 1 1 1 1)
                      (0 0 2 1 1 1 1 1 1 1)
                      (0 0 0 2 1 1 1 1 1 1)
                      (0 0 0 0 1 1 1 1 1 1)
                      (0 0 0 0 2 1 1 1 1 1))
                    '((0 0 0 0 0 2 1 1 1 1)
                      (0 0 0 0 0 0 1 1 1 1)
                      (0 0 0 0 0 0 2 1 1 1)
                      (0 0 0 0 0 0 0 2 1 1)
                      (0 0 0 0 0 0 0 0 0 0))
		    nil nil
		    ;; 2x
		    '((0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1))
		    '((1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 2 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 2 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1))
		    '((0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 2 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0))))

(defmacro pl/curve (dir)
  "Generate a curve XPM function for DIR."
  (pl/pattern-defun "curve" dir 4
                    '((0 0 0 0))
                    '((1 1 1 1)
                      (2 1 1 1)
                      (0 0 1 1)
                      (0 0 2 1)
                      (0 0 0 1)
                      (0 0 0 2))
                    '((0 0 0 2)
                      (0 0 0 1)
                      (0 0 2 1)
                      (0 0 1 1)
                      (2 1 1 1)
                      (1 1 1 1))
		    nil nil
		    ;; 2x
		    '((0 0 0 0 0 0 0 0))
		    '((1 1 1 1 1 1 1 1)
		      (1 1 1 1 1 1 1 1)
		      (1 1 1 1 1 1 1 1)
		      (0 0 1 1 1 1 1 1)
		      (0 0 0 2 1 1 1 1)
		      (0 0 0 0 2 1 1 1)
		      (0 0 0 0 0 2 1 1)
		      (0 0 0 0 0 0 1 1)
		      (0 0 0 0 0 0 1 1)
		      (0 0 0 0 0 0 0 1)
		      (0 0 0 0 0 0 0 1)
		      (0 0 0 0 0 0 0 1))
		    '((0 0 0 0 0 0 0 1)
		      (0 0 0 0 0 0 0 1)
		      (0 0 0 0 0 0 0 1)
		      (0 0 0 0 0 0 1 1)
		      (0 0 0 0 0 0 1 1)
		      (0 0 0 0 0 2 1 1)
		      (0 0 0 0 2 1 1 1)
		      (0 0 0 2 1 1 1 1)
		      (0 0 1 1 1 1 1 1)
		      (1 1 1 1 1 1 1 1)
		      (1 1 1 1 1 1 1 1)
		      (1 1 1 1 1 1 1 1))))

(defmacro pl/rounded (dir)
  "Generate a rounded XPM function for DIR."
  (pl/pattern-defun "rounded" dir 6
                    '((0 0 0 0 0 0))
                    '((2 1 1 1 1 1)
                      (0 0 2 1 1 1)
                      (0 0 0 0 1 1)
                      (0 0 0 0 2 1)
                      (0 0 0 0 0 1)
                      (0 0 0 0 0 2))
		    nil nil nil
		    ;; 2x
		    '((0 0 0 0 0 0 0 0 0 0 0 0))
		    '((1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 2 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 2 1 1 1 1)
		      (0 0 0 0 0 0 0 0 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 1 1)
		      (0 0 0 0 0 0 0 0 0 0 1 1)
		      (0 0 0 0 0 0 0 0 0 0 2 1)
		      (0 0 0 0 0 0 0 0 0 0 0 1)
		      (0 0 0 0 0 0 0 0 0 0 0 1))))

(defmacro pl/roundstub (dir)
  "Generate a roundstub XPM function for DIR."
  (pl/pattern-defun "roundstub" dir 3
                    '((0 0 0))
                    '((1 1 1)
                      (0 0 1)
                      (0 0 2))
                    '((0 0 2)
                      (0 0 1)
                      (1 1 1))
		    nil nil
		    ;; 2x
		    '((0 0 0 0 0 0))
		    '((1 1 1 1 1 1)
		      (2 1 1 1 1 1)
		      (0 0 0 2 1 1)
		      (0 0 0 0 1 1)
		      (0 0 0 0 0 1)
		      (0 0 0 0 0 1))
		    '((0 0 0 0 0 1)
		      (0 0 0 0 0 1)
		      (0 0 0 0 1 1)
		      (0 0 0 2 1 1)
		      (2 1 1 1 1 1)
		      (1 1 1 1 1 1))))

(defmacro pl/slant (dir)
  "Generate a slant XPM function for DIR."
  (let* ((row-modifier (if (eq dir 'left) 'identity 'reverse)))
    (pl/wrap-defun "slant" dir 'width
                   '((width (1- (ceiling height 2))))
                   `((cl-loop for i from 0 to (1- height)
                              concat (pl/pattern-to-string (,row-modifier (pl/row-pattern (/ i 2) width)))))
		   `((cl-loop for i from 0 to (1- (* height 2))
                              concat (pl/pattern-to-string (,row-modifier (pl/row-pattern (/ i 2) (* width 2)))))))))

(defmacro pl/wave (dir)
  "Generate a wave XPM function for DIR."
  (pl/pattern-defun "wave" dir 11
                    '((0 0 0 0 0 0 1 1 1 1 1))
                    '((2 1 1 1 1 1 1 1 1 1 1)
                      (0 0 1 1 1 1 1 1 1 1 1)
                      (0 0 0 1 1 1 1 1 1 1 1)
                      (0 0 0 2 1 1 1 1 1 1 1)
                      (0 0 0 0 1 1 1 1 1 1 1)
                      (0 0 0 0 2 1 1 1 1 1 1)
                      (0 0 0 0 0 1 1 1 1 1 1)
                      (0 0 0 0 0 1 1 1 1 1 1)
                      (0 0 0 0 0 2 1 1 1 1 1))
                    '((0 0 0 0 0 0 2 1 1 1 1)
                      (0 0 0 0 0 0 0 1 1 1 1)
                      (0 0 0 0 0 0 0 1 1 1 1)
                      (0 0 0 0 0 0 0 2 1 1 1)
                      (0 0 0 0 0 0 0 0 1 1 1)
                      (0 0 0 0 0 0 0 0 2 1 1)
                      (0 0 0 0 0 0 0 0 0 0 2))
		    nil nil
		    ;; 2x
		    '((0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1))
		    '((1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1))
		    '((0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 1 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1)
		      (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0))))

(defmacro pl/zigzag (dir)
  "Generate a zigzag pattern XPM function for DIR."
  (pl/pattern-defun "zigzag" dir 3
                    '((1 1 1)
                      (0 1 1)
                      (0 0 1)
                      (0 0 0)
                      (0 0 1)
                      (0 1 1))
		    nil nil nil nil
		    ;; 2x
		    '((1 1 1 1 1 1)
		      (0 1 1 1 1 1)
		      (0 0 1 1 1 1)
		      (0 0 0 1 1 1)
		      (0 0 0 0 1 1)
		      (0 0 0 0 0 1)
		      (0 0 0 0 0 0)
		      (0 0 0 0 0 1)
		      (0 0 0 0 1 1)
		      (0 0 0 1 1 1)
		      (0 0 1 1 1 1)
		      (0 1 1 1 1 1))))

(defmacro pl/nil (dir)
  "Generate a XPM function that returns nil for DIR."
  `(defun ,(intern (format "powerline-nil-%s" (symbol-name dir)))
     (face1 face2 &optional height)
     nil))

(defmacro pl/utf-8 (dir)
  "Generate function that returns raw utf-8 symbols."
  (let ((dir-name (symbol-name dir))
	(src-face (if (eq dir 'left) 'face1 'face2))
	(dst-face (if (eq dir 'left) 'face2 'face1)))
    `(defun ,(intern (format "powerline-utf-8-%s" dir-name))
       (face1 face2 &optional height)
       (powerline-raw
	(char-to-string ,(intern (format "powerline-utf-8-separator-%s"
					 dir-name)))
        (list :foreground (pl/background-color ,src-face)
              :background (pl/background-color ,dst-face)
              :inverse-video nil)))))


(provide 'powerline-separators)

;;; powerline-separators.el ends here