Move Python commands to separate library
This commit is contained in:
parent
82a7d84572
commit
00019a1e90
2 changed files with 203 additions and 167 deletions
|
@ -137,16 +137,6 @@ MODE1 is enabled and vice-versa."
|
||||||
|
|
||||||
;;;; Functions
|
;;;; 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 ()
|
(defun oni:after-save-func ()
|
||||||
"Function for `after-save-hook'."
|
"Function for `after-save-hook'."
|
||||||
(executable-make-buffer-file-executable-if-script-p)
|
(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 regfunc (point) (- (point) num))
|
||||||
(funcall wordfunc -1))))
|
(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 ()
|
(defun oni:current-jabber-status ()
|
||||||
"Return a string representing the current jabber status."
|
"Return a string representing the current jabber status."
|
||||||
(or (and (not *jabber-connected*) "Offline")
|
(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 "]"))
|
||||||
(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 ()
|
(defun oni:make-readable ()
|
||||||
"Make non-programming buffers a little more readable."
|
"Make non-programming buffers a little more readable."
|
||||||
(setq line-spacing .2))
|
(setq line-spacing .2))
|
||||||
|
@ -708,13 +670,6 @@ For `python-mode' I prefer `python-imenu-create-flat-index'."
|
||||||
(interactive)
|
(interactive)
|
||||||
(find-file "~/documents/org/index.org"))
|
(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)
|
(defun oni:split-window-interactive (dir)
|
||||||
"Split windows in direction DIR.
|
"Split windows in direction DIR.
|
||||||
|
|
||||||
|
@ -801,128 +756,6 @@ If no direction is given, don't split."
|
||||||
(projectile-rails-root))
|
(projectile-rails-root))
|
||||||
(rvm-activate-ruby-for (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
|
;;;; Module-specific settings
|
||||||
|
|
||||||
(auto-init appt)
|
(auto-init appt)
|
||||||
|
|
203
emacs/.emacs.d/site-lisp/oni-python.el
Normal file
203
emacs/.emacs.d/site-lisp/oni-python.el
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
;;; oni-python.el --- Extra Python commands -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2015 Tom Willemse
|
||||||
|
|
||||||
|
;; Author: Tom Willemse <tom@ryuslash.org>
|
||||||
|
;; 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; 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
|
Loading…
Reference in a new issue