From 00019a1e90c7969fdf36c17b762d13a6f91a1042 Mon Sep 17 00:00:00 2001 From: Tom Willemse Date: Wed, 16 Dec 2015 22:26:25 +0100 Subject: [PATCH] Move Python commands to separate library --- emacs/.emacs.d/init.el | 167 -------------------- emacs/.emacs.d/site-lisp/oni-python.el | 203 +++++++++++++++++++++++++ 2 files changed, 203 insertions(+), 167 deletions(-) create mode 100644 emacs/.emacs.d/site-lisp/oni-python.el diff --git a/emacs/.emacs.d/init.el b/emacs/.emacs.d/init.el index 729f682..50fe8f1 100644 --- a/emacs/.emacs.d/init.el +++ b/emacs/.emacs.d/init.el @@ -137,16 +137,6 @@ MODE1 is enabled and vice-versa." ;;;; Functions -(defun oni:add-import-from (package import) - (interactive - (list (completing-read "From package: " (oni:collect-from-imports)) - (read-string "Import: "))) - (save-excursion - (goto-char (point-min)) - (search-forward (concat "from " package " import (")) - (insert "\n " import ",") - (oni:sort-imports))) - (defun oni:after-save-func () "Function for `after-save-hook'." (executable-make-buffer-file-executable-if-script-p) @@ -211,15 +201,6 @@ But only if it is a maildir inbox." (funcall regfunc (point) (- (point) num)) (funcall wordfunc -1)))) -(defun oni:collect-from-imports () - (let (results) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward "from \\(.+\\) import" nil :noerror) - (push (buffer-substring-no-properties (match-beginning 1) - (match-end 1)) results))) - results)) - (defun oni:current-jabber-status () "Return a string representing the current jabber status." (or (and (not *jabber-connected*) "Offline") @@ -298,25 +279,6 @@ But only if it is a maildir inbox." (local-unset-key (kbd "]")) (local-unset-key (kbd "}"))) -(defun oni:make-import-multiline (from-point to-point) - (interactive (list (line-beginning-position) - (line-end-position))) - (goto-char from-point) - (search-forward "import" to-point) - (insert " (\n") - (delete-horizontal-space) - (let ((imports-start (point)) imports-end) - (while (search-forward "," to-point :noeror) - (insert "\n") - (delete-horizontal-space)) - (end-of-line) - (insert ",\n") - (setf imports-end (point)) - (insert ")") - (python-indent-shift-right imports-start imports-end) - (forward-line -1) - (oni:sort-imports))) - (defun oni:make-readable () "Make non-programming buffers a little more readable." (setq line-spacing .2)) @@ -708,13 +670,6 @@ For `python-mode' I prefer `python-imenu-create-flat-index'." (interactive) (find-file "~/documents/org/index.org")) -(defun oni:sort-imports () - "Sort python multiline imports using `()'." - (interactive) - (save-excursion - (sort-lines nil (1+ (search-backward "(")) - (1- (search-forward ")"))))) - (defun oni:split-window-interactive (dir) "Split windows in direction DIR. @@ -801,128 +756,6 @@ If no direction is given, don't split." (projectile-rails-root)) (rvm-activate-ruby-for (projectile-rails-root)))) -;;;; Tests - -(stante-after ert - (ert-deftest oni:add-import-from () - (with-temp-buffer - (python-mode) - (insert "from myaethon2.core.administration.models import ( - Client, - Contact, - Individual, - Location, -)") - (oni:add-import-from "myaethon2.core.administration.models" "Debtor") - (should (equal (buffer-substring-no-properties (point-min) (point-max)) - "from myaethon2.core.administration.models import ( - Client, - Contact, - Debtor, - Individual, - Location, -)")))) - - (ert-deftest oni:collect-from-imports () - (with-temp-buffer - (python-mode) - (insert "import calendar as cal -import datetime - -from django.conf import settings -from django.contrib import messages -from django.contrib.auth.decorators import login_required, permission_required -from django.core.context_processors import csrf -from django.core.exceptions import PermissionDenied -from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger -from django.core.urlresolvers import reverse -from django.db import transaction -from django.db.models import Q -from django.shortcuts import get_object_or_404, render -from django.utils import formats -from django.utils.translation import ugettext as _ - -from myaethon2.core.business_units import BU -from myaethon2.core.forms import MultiFormWrapper -from myaethon2.core.models import AUser, Service -from myaethon2.core.planning.models import Booking, JOB_TYPES -from myaethon2.core.util import simplify_timedelta -from myaethon2.core.views import SearchAndSortListView -from myaethon2.jobs import forms, status -from myaethon2.jobs.models import Assignment, Job, JobGroup -from myaethon2.jobs.util import JobFactory -from myaethon2.workers.models import Worker -from myaethon2.export import Exporter, XLSGenerator - -from django.http import ( - HttpResponseForbidden, - HttpResponseNotAllowed, - HttpResponseRedirect, -) - -from django.views.generic import ( - CreateView, - DeleteView, - DetailView, - ListView, - UpdateView, -) - -from myaethon2.core.administration.models import ( - Client, - Contact, - Debtor, - Individual, - Location, -) - -from myaethon2.core.decorators import ( - json_response, - protect_with, - with_help_text, -)") - (should (equal (sort (oni:collect-from-imports) #'string-lessp) - '("django.conf" - "django.contrib" - "django.contrib.auth.decorators" - "django.core.context_processors" - "django.core.exceptions" - "django.core.paginator" - "django.core.urlresolvers" - "django.db" - "django.db.models" - "django.http" - "django.shortcuts" - "django.utils" - "django.utils.translation" - "django.views.generic" - "myaethon2.core.administration.models" - "myaethon2.core.business_units" - "myaethon2.core.decorators" - "myaethon2.core.forms" - "myaethon2.core.models" - "myaethon2.core.planning.models" - "myaethon2.core.util" - "myaethon2.core.views" - "myaethon2.export" - "myaethon2.jobs" - "myaethon2.jobs.models" - "myaethon2.jobs.util" - "myaethon2.workers.models"))))) - - (ert-deftest oni:make-import-multiline () - (with-temp-buffer - (python-mode) - (insert "from myaethon2.core.administration.models import Contact, Individual, Client, Location") - (oni:make-import-multiline (line-beginning-position) (line-end-position)) - (should (equal (buffer-substring-no-properties (point-min) (point-max)) - "from myaethon2.core.administration.models import ( - Client, - Contact, - Individual, - Location, -)"))))) - ;;;; Module-specific settings (auto-init appt) diff --git a/emacs/.emacs.d/site-lisp/oni-python.el b/emacs/.emacs.d/site-lisp/oni-python.el new file mode 100644 index 0000000..6a0ff03 --- /dev/null +++ b/emacs/.emacs.d/site-lisp/oni-python.el @@ -0,0 +1,203 @@ +;;; oni-python.el --- Extra Python commands -*- lexical-binding: t; -*- + +;; Copyright (C) 2015 Tom Willemse + +;; Author: Tom Willemse +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; Here are some extra Emacs commands for working with Python source +;; code. + +;;; Code: + +(require 'python) + +;;;###autoload +(defun oni:add-import-from (package import) + "Add a Python import statement at the beginning of the module." + (interactive + (list (completing-read "From package: " (oni:collect-from-imports)) + (read-string "Import: "))) + (save-excursion + (goto-char (point-min)) + (search-forward (concat "from " package " import (")) + (insert "\n " import ",") + (oni:sort-imports))) + +(defun oni:collect-from-imports () + "Find all modules from which names are imported in the current file." + (let (results) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "from \\(.+\\) import" nil :noerror) + (push (buffer-substring-no-properties (match-beginning 1) + (match-end 1)) results))) + results)) + +;;;###autoload +(defun oni:make-import-multiline (from-point to-point) + "Turn an import statement into a multi-line import statement." + (interactive (list (line-beginning-position) + (line-end-position))) + (goto-char from-point) + (search-forward "import" to-point) + (insert " (\n") + (delete-horizontal-space) + (let ((imports-start (point)) imports-end) + (while (search-forward "," to-point :noeror) + (insert "\n") + (delete-horizontal-space)) + (end-of-line) + (insert ",\n") + (setf imports-end (point)) + (insert ")") + (python-indent-shift-right imports-start imports-end) + (forward-line -1) + (oni:sort-imports))) + +;;;###autoload +(defun oni:sort-imports () + "Sort python multiline imports using `()'." + (interactive) + (save-excursion + (sort-lines nil (1+ (search-backward "(")) + (1- (search-forward ")"))))) + +;;; Tests + +(ert-deftest oni:add-import-from () + (with-temp-buffer + (python-mode) + (insert "from myaethon2.core.administration.models import ( + Client, + Contact, + Individual, + Location, +)") + (oni:add-import-from "myaethon2.core.administration.models" "Debtor") + (should (equal (buffer-substring-no-properties (point-min) (point-max)) + "from myaethon2.core.administration.models import ( + Client, + Contact, + Debtor, + Individual, + Location, +)")))) + +(ert-deftest oni:collect-from-imports () + (with-temp-buffer + (python-mode) + (insert "import calendar as cal +import datetime + +from django.conf import settings +from django.contrib import messages +from django.contrib.auth.decorators import login_required, permission_required +from django.core.context_processors import csrf +from django.core.exceptions import PermissionDenied +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger +from django.core.urlresolvers import reverse +from django.db import transaction +from django.db.models import Q +from django.shortcuts import get_object_or_404, render +from django.utils import formats +from django.utils.translation import ugettext as _ + +from myaethon2.core.business_units import BU +from myaethon2.core.forms import MultiFormWrapper +from myaethon2.core.models import AUser, Service +from myaethon2.core.planning.models import Booking, JOB_TYPES +from myaethon2.core.util import simplify_timedelta +from myaethon2.core.views import SearchAndSortListView +from myaethon2.jobs import forms, status +from myaethon2.jobs.models import Assignment, Job, JobGroup +from myaethon2.jobs.util import JobFactory +from myaethon2.workers.models import Worker +from myaethon2.export import Exporter, XLSGenerator + +from django.http import ( + HttpResponseForbidden, + HttpResponseNotAllowed, + HttpResponseRedirect, +) + +from django.views.generic import ( + CreateView, + DeleteView, + DetailView, + ListView, + UpdateView, +) + +from myaethon2.core.administration.models import ( + Client, + Contact, + Debtor, + Individual, + Location, +) + +from myaethon2.core.decorators import ( + json_response, + protect_with, + with_help_text, +)") + (should (equal (sort (oni:collect-from-imports) #'string-lessp) + '("django.conf" + "django.contrib" + "django.contrib.auth.decorators" + "django.core.context_processors" + "django.core.exceptions" + "django.core.paginator" + "django.core.urlresolvers" + "django.db" + "django.db.models" + "django.http" + "django.shortcuts" + "django.utils" + "django.utils.translation" + "django.views.generic" + "myaethon2.core.administration.models" + "myaethon2.core.business_units" + "myaethon2.core.decorators" + "myaethon2.core.forms" + "myaethon2.core.models" + "myaethon2.core.planning.models" + "myaethon2.core.util" + "myaethon2.core.views" + "myaethon2.export" + "myaethon2.jobs" + "myaethon2.jobs.models" + "myaethon2.jobs.util" + "myaethon2.workers.models"))))) + +(ert-deftest oni:make-import-multiline () + (with-temp-buffer + (python-mode) + (insert "from myaethon2.core.administration.models import Contact, Individual, Client, Location") + (oni:make-import-multiline (line-beginning-position) (line-end-position)) + (should (equal (buffer-substring-no-properties (point-min) (point-max)) + "from myaethon2.core.administration.models import ( + Client, + Contact, + Individual, + Location, +)")))) + +(provide 'oni-python) +;;; oni-python.el ends here