summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/post/cedit-and-paredit.md4
-rw-r--r--content/post/emacs-package-archive-statistics.md40
-rw-r--r--content/post/opening-projects-with-projectile.md20
-rw-r--r--content/post/repository-management-with-ghq.md16
-rw-r--r--content/post/self-hosted-git.md29
5 files changed, 54 insertions, 55 deletions
diff --git a/content/post/cedit-and-paredit.md b/content/post/cedit-and-paredit.md
index a8b65a1..23fb1c4 100644
--- a/content/post/cedit-and-paredit.md
+++ b/content/post/cedit-and-paredit.md
@@ -28,12 +28,12 @@ paredit. Turns out it provides
28that control whether a space should be inserted. So, solving the 28that control whether a space should be inserted. So, solving the
29formatting issue turned out to be pretty simple: 29formatting issue turned out to be pretty simple:
30 30
31{{< highlight cl >}} 31```elisp
32(defun ap/cedit-space-delimiter-p (endp delimiter) 32(defun ap/cedit-space-delimiter-p (endp delimiter)
33"Don't insert a space before delimiters in c-style modes" 33"Don't insert a space before delimiters in c-style modes"
34(not cedit-mode)) 34(not cedit-mode))
35(add-to-list 'paredit-space-for-delimiter-predicates #'ap/cedit-space-delimiter-p) 35(add-to-list 'paredit-space-for-delimiter-predicates #'ap/cedit-space-delimiter-p)
36{{< /highlight >}} 36```
37 37
38Hopefully that saves someone some time if they try to use the two 38Hopefully that saves someone some time if they try to use the two
39together. 39together.
diff --git a/content/post/emacs-package-archive-statistics.md b/content/post/emacs-package-archive-statistics.md
index 5f74f18..2275c9a 100644
--- a/content/post/emacs-package-archive-statistics.md
+++ b/content/post/emacs-package-archive-statistics.md
@@ -10,13 +10,13 @@ I use [cask][] for managing the dependencies of my Emacs
10configuration. Whenever I opened my `Cask` file, I wondered if I 10configuration. Whenever I opened my `Cask` file, I wondered if I
11really was using all the sources I had defined: 11really was using all the sources I had defined:
12 12
13{{< highlight cl >}} 13```elisp
14(source gnu) 14(source gnu)
15(source marmalade) 15(source marmalade)
16(source melpa) 16(source melpa)
17(source melpa-stable) 17(source melpa-stable)
18(source org) 18(source org)
19{{< /highlight >}} 19```
20 20
21It seemed quite strange that we have so many package repositories in 21It seemed quite strange that we have so many package repositories in
22the Emacs world and I'm not even using all of them. I find this state 22the Emacs world and I'm not even using all of them. I find this state
@@ -44,29 +44,29 @@ decided to try to figure out how to generate some usage statistics.
44I found [how to get a list of installed packages][], but that just gives 44I found [how to get a list of installed packages][], but that just gives
45a list: 45a list:
46 46
47{{< highlight cl >}} 47```elisp
48(ace-jump-mode ag auto-compile auto-indent-mode autopair ...) 48(ace-jump-mode ag auto-compile auto-indent-mode autopair ...)
49{{< /highlight >}} 49```
50 50
51I needed to get more information about those packages. I looked at 51I needed to get more information about those packages. I looked at
52where `list-packages` gets that information from. It seems that 52where `list-packages` gets that information from. It seems that
53`package-archive-contents` is a list of cons cells: 53`package-archive-contents` is a list of cons cells:
54 54
55{{< highlight cl >}} 55```elisp
56(org-plus-contrib . 56(org-plus-contrib .
57 [(20140714) 57 [(20140714)
58 nil "Outline-based notes management and organizer" tar "org"]) 58 nil "Outline-based notes management and organizer" tar "org"])
59{{< /highlight >}} 59```
60 60
61Then created a function to loop over the contents of 61Then created a function to loop over the contents of
62`package-activated-list`, retrieving the corresponding contents of 62`package-activated-list`, retrieving the corresponding contents of
63`package-archive-contents`: 63`package-archive-contents`:
64 64
65{{< highlight cl >}} 65```elisp
66(defun package-list-installed () 66(defun package-list-installed ()
67 (loop for pkg in package-activated-list 67 (loop for pkg in package-activated-list
68 collect (assq pkg package-archive-contents))) 68 collect (assq pkg package-archive-contents)))
69{{< /highlight >}} 69```
70 70
71This generates a list of arrays from `package-archive-contents`. 71This generates a list of arrays from `package-archive-contents`.
72There are some helper functions in package.el such as 72There are some helper functions in package.el such as
@@ -74,11 +74,11 @@ There are some helper functions in package.el such as
74needed. I happened to be using a pretest version of Emacs at the time 74needed. I happened to be using a pretest version of Emacs at the time
75and didn't know that it's not in 24.3, so I just made sure it was defined: 75and didn't know that it's not in 24.3, so I just made sure it was defined:
76 76
77{{< highlight cl >}} 77```elisp
78(if (not (fboundp #'package-desc-archive)) 78(if (not (fboundp #'package-desc-archive))
79 (defsubst package-desc-archive (desc) 79 (defsubst package-desc-archive (desc)
80 (aref desc (1- (length desc))))) 80 (aref desc (1- (length desc)))))
81{{< /highlight >}} 81```
82 82
83Weirdly, some of the arrays (seemingly the ones from the 83Weirdly, some of the arrays (seemingly the ones from the
84[org archive][]) had a different length, but the repository/archive was 84[org archive][]) had a different length, but the repository/archive was
@@ -89,7 +89,7 @@ To generate a list of statistics, I just needed to loop over the
89installed packages from `package-list-installed` and update a count 89installed packages from `package-list-installed` and update a count
90for each archive: 90for each archive:
91 91
92{{< highlight cl >}} 92```elisp
93(defun package-archive-stats () 93(defun package-archive-stats ()
94 (let ((archives (makehash)) 94 (let ((archives (makehash))
95 (assoc '())) 95 (assoc '()))
@@ -101,32 +101,32 @@ for each archive:
101 (let ((pkg-arc (package-desc-archive (cdr pkg)))) 101 (let ((pkg-arc (package-desc-archive (cdr pkg))))
102 (incf (gethash pkg-arc archives))))) 102 (incf (gethash pkg-arc archives)))))
103 assoc)) 103 assoc))
104{{< /highlight >}} 104```
105 105
106Running this gives a list of cons cells: 106Running this gives a list of cons cells:
107 107
108{{< highlight cl >}} 108```elisp
109(("gnu" . 0) 109(("gnu" . 0)
110 ("org" . 1) 110 ("org" . 1)
111 ("melpa-stable" . 2) 111 ("melpa-stable" . 2)
112 ("melpa" . 106) 112 ("melpa" . 106)
113 ("marmalade" . 1)) 113 ("marmalade" . 1))
114{{< /highlight >}} 114```
115 115
116I wrapped it in an interactive function so that I could check the 116I wrapped it in an interactive function so that I could check the
117numbers quickly: 117numbers quickly:
118 118
119{{< highlight cl >}} 119```elisp
120(defun package-show-archive-stats () 120(defun package-show-archive-stats ()
121 (interactive) 121 (interactive)
122 (message "%s" (package-archive-stats))) 122 (message "%s" (package-archive-stats)))
123{{< /highlight >}} 123```
124 124
125With that, I removed `(source gnu)` from my `Cask` file. Now I had 125With that, I removed `(source gnu)` from my `Cask` file. Now I had
126another question. What package was installed from [marmalade][]? In 126another question. What package was installed from [marmalade][]? In
127the lisp fashion, I created yet another function: 127the lisp fashion, I created yet another function:
128 128
129{{< highlight cl >}} 129```elisp
130(defun package-show-installed-from-archive (archive) 130(defun package-show-installed-from-archive (archive)
131 (interactive (list (helm-comp-read "Archive: " (mapcar #'car package-archives) 131 (interactive (list (helm-comp-read "Archive: " (mapcar #'car package-archives)
132 :must-match t))) 132 :must-match t)))
@@ -136,15 +136,15 @@ the lisp fashion, I created yet another function:
136 (if (called-interactively-p) 136 (if (called-interactively-p)
137 (message "%s" from-arc) 137 (message "%s" from-arc)
138 from-arc))) 138 from-arc)))
139{{< /highlight >}} 139```
140(Non-helm users can replace `helm-comp-read` with 140(Non-helm users can replace `helm-comp-read` with
141`ido-completing-read` or similar) 141`ido-completing-read` or similar)
142 142
143Running this with the argument `"marmalade"` gives: 143Running this with the argument `"marmalade"` gives:
144 144
145{{< highlight cl >}} 145```elisp
146(php-extras) 146(php-extras)
147{{< /highlight >}} 147```
148 148
149I checked on [MELPA Stable][] and [MELPA][], but it's not available 149I checked on [MELPA Stable][] and [MELPA][], but it's not available
150there. Given that I use [php-extras][] quite a bit at work, I can't remove 150there. Given that I use [php-extras][] quite a bit at work, I can't remove
diff --git a/content/post/opening-projects-with-projectile.md b/content/post/opening-projects-with-projectile.md
index 04f8cb6..d88d309 100644
--- a/content/post/opening-projects-with-projectile.md
+++ b/content/post/opening-projects-with-projectile.md
@@ -12,30 +12,30 @@ With this in mind, I decided to try to add support for opening projects under a
12 12
13I saw that projectile uses [Dash.el][] in some places, and after reading about [anaphoric macros], I decided that I'd try to use them to aid me. 13I saw that projectile uses [Dash.el][] in some places, and after reading about [anaphoric macros], I decided that I'd try to use them to aid me.
14 14
15{{% highlight cl %}} 15```elisp
16(defun ap/subfolder-projects (dir) 16(defun ap/subfolder-projects (dir)
17 (--map (file-relative-name it dir) 17 (--map (file-relative-name it dir)
18 (-filter (lambda (subdir) 18 (-filter (lambda (subdir)
19 (--reduce-from (or acc (funcall it subdir)) nil 19 (--reduce-from (or acc (funcall it subdir)) nil
20 projectile-project-root-files-functions)) 20 projectile-project-root-files-functions))
21 (-filter #'file-directory-p (directory-files dir t "\\<"))))) 21 (-filter #'file-directory-p (directory-files dir t "\\<")))))
22{{% /highlight %}} 22```
23 23
24First, this filters the non-special files under `dir`, filtering non-directories. Then it runs the list of `projectile-project-root-files-functions` on it to determine if it looks like a projectile project. To make the list more readable, it makes the filenames relative to the passed-in directory. It runs like this: 24First, this filters the non-special files under `dir`, filtering non-directories. Then it runs the list of `projectile-project-root-files-functions` on it to determine if it looks like a projectile project. To make the list more readable, it makes the filenames relative to the passed-in directory. It runs like this:
25 25
26{{% highlight cl %}} 26```elisp
27(ap/subfolder-projects "~/projects") => 27(ap/subfolder-projects "~/projects") =>
28("dotfiles" "ggtags" …) 28("dotfiles" "ggtags" …)
29{{% /highlight %}} 29```
30 30
31So, we've got ourselves a list, but now we need to be able to open the project that's there, even though the folders are relative. 31So, we've got ourselves a list, but now we need to be able to open the project that's there, even though the folders are relative.
32 32
33{{% highlight cl %}} 33```elisp
34(defun ap/open-subfolder-project (from-dir &optional arg) 34(defun ap/open-subfolder-project (from-dir &optional arg)
35 (let ((project-dir (projectile-completing-read "Open project: " 35 (let ((project-dir (projectile-completing-read "Open project: "
36 (ap/subfolder-projects from-dir)))) 36 (ap/subfolder-projects from-dir))))
37 (projectile-switch-project-by-name (expand-file-name project-dir from-dir) arg))) 37 (projectile-switch-project-by-name (expand-file-name project-dir from-dir) arg)))
38{{% /highlight %}} 38```
39 39
40By wrapping the call to `ap/subfolder-projects` in another function that takes the same directory argument, we can re-use the project parent directory and expand the selected project name into an absolute path before passing it to `projectile-switch-project-by-name`. 40By wrapping the call to `ap/subfolder-projects` in another function that takes the same directory argument, we can re-use the project parent directory and expand the selected project name into an absolute path before passing it to `projectile-switch-project-by-name`.
41 41
@@ -43,7 +43,7 @@ We get support for multiple completion systems for free, since projectile has a
43 43
44Then I defined some helper functions to make it easy to open work and home projects. 44Then I defined some helper functions to make it easy to open work and home projects.
45 45
46{{% highlight cl %}} 46```elisp
47(defvar work-project-directory "~/work") 47(defvar work-project-directory "~/work")
48(defvar home-project-directory "~/projects") 48(defvar home-project-directory "~/projects")
49 49
@@ -54,7 +54,7 @@ Then I defined some helper functions to make it easy to open work and home proje
54(defun ap/open-home-project (&optional arg) 54(defun ap/open-home-project (&optional arg)
55 (interactive "P") 55 (interactive "P")
56 (ap/open-subfolder-project home-project-directory arg)) 56 (ap/open-subfolder-project home-project-directory arg))
57{{% /highlight %}} 57```
58 58
59I could probably simplify this with a macro, but I'm not sure that there's much advantage in it. I only have two project types right now, after all. 59I could probably simplify this with a macro, but I'm not sure that there's much advantage in it. I only have two project types right now, after all.
60 60
@@ -62,14 +62,14 @@ With this all set up, whenever I want to start working on a project I just type
62 62
63I also considered trying to add all the projects under a directory to the projectile known project list. I didn't find it quite as easy to use, but it's available below if anyone would prefer that style. 63I also considered trying to add all the projects under a directory to the projectile known project list. I didn't find it quite as easy to use, but it's available below if anyone would prefer that style.
64 64
65{{% highlight cl %}} 65```elisp
66(defun ap/-add-known-subfolder-projects (dir) 66(defun ap/-add-known-subfolder-projects (dir)
67 (-map #'projectile-add-known-project (--map (concat (file-name-as-directory dir) it) (ap/subfolder-projects dir)))) 67 (-map #'projectile-add-known-project (--map (concat (file-name-as-directory dir) it) (ap/subfolder-projects dir))))
68 68
69(defun ap/add-known-subfolder-projects () 69(defun ap/add-known-subfolder-projects ()
70 (interactive) 70 (interactive)
71 (ap/-add-known-subfolder-projects (ido-read-directory-name "Add projects under: "))) 71 (ap/-add-known-subfolder-projects (ido-read-directory-name "Add projects under: ")))
72{{% /highlight %}} 72```
73 73
74[Projectile]: https://github.com/bbatsov/projectile 74[Projectile]: https://github.com/bbatsov/projectile
75[Dash.el]: https://github.com/magnars/dash.el 75[Dash.el]: https://github.com/magnars/dash.el
diff --git a/content/post/repository-management-with-ghq.md b/content/post/repository-management-with-ghq.md
index 6006605..d831c9e 100644
--- a/content/post/repository-management-with-ghq.md
+++ b/content/post/repository-management-with-ghq.md
@@ -8,10 +8,10 @@ I recently encountered [ghq][], a tool for automatically organising VCS-backed
8projects automatically. Give it a repository URL, it will clone a project to 8projects automatically. Give it a repository URL, it will clone a project to
9your projects dir (set by `$GHQ_ROOT`) like so: 9your projects dir (set by `$GHQ_ROOT`) like so:
10 10
11{{< highlight sh >}} 11```sh
12$ ghq get https://github.com/motemen/ghq 12$ ghq get https://github.com/motemen/ghq
13# Runs `git clone https://github.com/motemen/ghq ~/.ghq/github.com/motemen/ghq` 13# Runs `git clone https://github.com/motemen/ghq ~/.ghq/github.com/motemen/ghq`
14{{< /highlight >}} 14```
15 15
16I don't like the idea of having projects hidden away, so I set 16I don't like the idea of having projects hidden away, so I set
17`$GHQ_ROOT` to `$HOME/projects`. 17`$GHQ_ROOT` to `$HOME/projects`.
@@ -23,11 +23,11 @@ I wanted a nicer way to visit project directories. Since I'm
23using [fzf][] as a fuzzy-finder, I thought it would be nice to use it 23using [fzf][] as a fuzzy-finder, I thought it would be nice to use it
24for this. I created a simple function, `fp` (find project) to do that: 24for this. I created a simple function, `fp` (find project) to do that:
25 25
26{{< highlight sh >}} 26```sh
27fp () { 27fp () {
28 ghq look $(ghq list | fzf +m) 28 ghq look $(ghq list | fzf +m)
29} 29}
30{{< /highlight >}} 30```
31 31
32I ran into some issues with the subshell of `ghq look` and wondered 32I ran into some issues with the subshell of `ghq look` and wondered
33whether it might be possible to create a zsh command to remove the 33whether it might be possible to create a zsh command to remove the
@@ -36,7 +36,7 @@ need for a subshell.
36I found that `fzf` includes a [cd-widget function][fzf-cd-widget] and created 36I found that `fzf` includes a [cd-widget function][fzf-cd-widget] and created
37something similar that uses `ghq` instead of `find`: 37something similar that uses `ghq` instead of `find`:
38 38
39{{< highlight sh >}} 39```sh
40cd-project-widget () { 40cd-project-widget () {
41 local cmd="ghq list" 41 local cmd="ghq list"
42 setopt localoptions pipefail 2> /dev/null 42 setopt localoptions pipefail 2> /dev/null
@@ -52,7 +52,7 @@ cd-project-widget () {
52 return $ret 52 return $ret
53} 53}
54zle -N cd-project-widget 54zle -N cd-project-widget
55{{< /highlight >}} 55```
56 56
57It should be quite simple to modify it to work with other 57It should be quite simple to modify it to work with other
58fuzzy-finders. The basic idea is to show the output of `ghq list` for 58fuzzy-finders. The basic idea is to show the output of `ghq list` for
@@ -62,9 +62,9 @@ to print the correct directory for `cd`.
62What's really nice about this, is that I can bind it to a key 62What's really nice about this, is that I can bind it to a key
63sequence: 63sequence:
64 64
65{{< highlight sh >}} 65```sh
66bindkey '\es' cd-project-widget 66bindkey '\es' cd-project-widget
67{{< /highlight >}} 67```
68 68
69Now I can press `M-s` in a shell, start typing "dotfiles" and press enter to `cd` 69Now I can press `M-s` in a shell, start typing "dotfiles" and press enter to `cd`
70to my [dotfiles][] project. Pretty neat! 70to my [dotfiles][] project. Pretty neat!
diff --git a/content/post/self-hosted-git.md b/content/post/self-hosted-git.md
index c73d255..883ea0f 100644
--- a/content/post/self-hosted-git.md
+++ b/content/post/self-hosted-git.md
@@ -62,22 +62,22 @@ means that I can create a remote repository automatically by cloning a
62repository URL that doesn't already exist. 62repository URL that doesn't already exist.
63I can clone and create a new repo simultaneously like so: 63I can clone and create a new repo simultaneously like so:
64 64
65{{< highlight shell-session >}} 65```shell
66cd ~/projects 66cd ~/projects
67git clone alanpearce.eu:some-new-repository 67git clone alanpearce.eu:some-new-repository
68{{< /highlight >}} 68```
69 69
70But with [ghq][], which I [blogged about before][using-ghq], I don't 70But with [ghq][], which I [blogged about before][using-ghq], I don't
71have to concern myself with where to put the repository: 71have to concern myself with where to put the repository:
72 72
73{{< highlight shell-session >}} 73```shell
74$ ghq get alanpearce.eu:some-new-repository 74$ ghq get alanpearce.eu:some-new-repository
75 clone ssh://alanpearce.eu/some-new-repository -> /Volumes/Code/projects/alanpearce.eu/some-new-repository 75 clone ssh://alanpearce.eu/some-new-repository -> /Volumes/Code/projects/alanpearce.eu/some-new-repository
76 git clone ssh://alanpearce.eu/some-new-repository /Volumes/Code/projects/alanpearce.eu/some-new-repository 76 git clone ssh://alanpearce.eu/some-new-repository /Volumes/Code/projects/alanpearce.eu/some-new-repository
77Cloning into '/Volumes/Code/projects/alanpearce.eu/some-new-repository'... 77Cloning into '/Volumes/Code/projects/alanpearce.eu/some-new-repository'...
78Initialized empty Git repository in /var/lib/gitolite/repositories/some-new-repository.git/ 78Initialized empty Git repository in /var/lib/gitolite/repositories/some-new-repository.git/
79warning: You appear to have cloned an empty repository. 79warning: You appear to have cloned an empty repository.
80{{< /highlight >}} 80```
81 81
82The nice URLs come from this piece of my SSH configuration: 82The nice URLs come from this piece of my SSH configuration:
83 83
@@ -92,10 +92,10 @@ Host alanpearce.eu
92This repository would be private by default, but I can change that by an 92This repository would be private by default, but I can change that by an
93SSH command. Here's how I would do it: 93SSH command. Here's how I would do it:
94 94
95{{< highlight shell-session >}} 95```shell
96$ ssh alanpearce.eu perms some-new-repository + READERS gitweb 96ssh alanpearce.eu perms some-new-repository + READERS gitweb
97$ ssh alanpearce.eu perms some-new-repository + READERS daemon 97ssh alanpearce.eu perms some-new-repository + READERS daemon
98{{< /highlight >}} 98```
99 99
100The first command makes it visible in cgit, whilst the second makes it 100The first command makes it visible in cgit, whilst the second makes it
101clonable via `git://` url. I can make a repository 101clonable via `git://` url. I can make a repository
@@ -105,15 +105,14 @@ user and not `gitweb`, if I wanted.
105I can also add or change the description of a repository shown on cgit like 105I can also add or change the description of a repository shown on cgit like
106so: 106so:
107 107
108{{< highlight shell-session >}} 108```shell
109$ ssh alanpearce.eu desc some-new-repository 'A new repository' 109ssh alanpearce.eu desc some-new-repository 'A new repository'
110{{< /highlight >}} 110```
111 111
112All the remote commands exposed by gitolite are described in the 112All the remote commands exposed by gitolite are described in the
113`help` command 113`help` command e.g. `ssh alanpearce.eu help`
114 114
115{{< highlight shell-session >}} 115```
116$ ssh alanpearce.eu help
117hello alan, this is gitolite@oak running gitolite3 (unknown) on git 2.12.2 116hello alan, this is gitolite@oak running gitolite3 (unknown) on git 2.12.2
118 117
119list of remote commands available: 118list of remote commands available:
@@ -126,7 +125,7 @@ list of remote commands available:
126 perms 125 perms
127 writable 126 writable
128 127
129{{< /highlight >}} 128```
130 129
131## Conclusion 130## Conclusion
132 131