gnomenm.el 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. ;;; gnomenm.el --- Emacs interface to Gnome nmcli command
  2. ;; Copyright (C) 2013 Nic Ferrier
  3. ;; Copyright (C) 2019 Jelle Licht <jlicht@fsfe.org>
  4. ;; Author: Nic Ferrier <nferrier@ferrier.me.uk>
  5. ;; Keywords: processes, hardware
  6. ;; URL: https://notabug.org/jlicht/emacs-nm
  7. ;; Version: 0.0.9
  8. ;; Package-requires: ((s "1.9.0")(dash "2.3.0")(kv "0.0.19"))
  9. ;; This program is free software; you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation, either version 3 of the License, or
  12. ;; (at your option) any later version.
  13. ;; This program is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ;; GNU General Public License for more details.
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. ;;; Commentary:
  20. ;; nmcli is a pain to use so here's a simple Emacs interface.
  21. ;;; Code:
  22. (eval-when-compile
  23. (require 'cl-lib))
  24. (require 's)
  25. (require 'dash)
  26. (require 'kv)
  27. (defvar gnomenm/enabled nil
  28. "Whether gnomenm is enabled or not.")
  29. (defun gnomenm/list ()
  30. "List the connections.
  31. Produces a list like:
  32. (\"PGGuest\" \"03a11865-3953-4052-aa67-34bc891d3c61\" \"802-11-wireless\" \"Thu 13 Feb 2014 14:12:27 GMT\")
  33. (\"Norwegian Internet Access 9ca4914a-8feb-45bf-bf90-ea472d2ee98a\" \"802-11-wireless\" \"Wed 20 Nov 2013 17:45:45 GMT\")
  34. (\"GIB_PUBLIC\" \"631d8f69-1574-4687-9a00-18d29386d2c4\" \"802-11-wireless\" \"Wed 23 Oct 2013 19:19:29 BST\")
  35. (\"bwinparty\" \"23534f3e-f5c5-4ec8-86a9-7c3f8866d6c7\" \"vpn\" \"Sat 15 Feb 2014 08:03:32 GMT\")
  36. (\"SIL\" \"d047093c-b6c8-42db-8d3e-7888bbd39a21\" \"802-11-wireless\" \"never\")
  37. (\"NETGEAR_EXT\" \"3eab3930-7e67-402c-9fec-471cd062c97d\" \"802-11-wireless\" \"Tue 10 Dec 2013 12:14:26 GMT\")
  38. "
  39. (cdr
  40. (->> (split-string (shell-command-to-string "nmcli con show") "\n")
  41. (-keep (lambda (l)
  42. (->> (split-string l " ")
  43. (-keep (lambda (f)
  44. (let ((a (s-trim f)))
  45. (when (not (equal a "")) a))))))))))
  46. (defun gnomenm/enable ()
  47. "Turn on WIFI."
  48. (shell-command-to-string "nmcli -t -f net-enabled nm wifi on")
  49. (message "gnomenm wifi enabled")
  50. (setq gnomenm/enabled t))
  51. (defun gnomenm/disable ()
  52. "Turn off WIFI."
  53. (shell-command-to-string "nmcli -t -f net-enabled nm wifi off")
  54. (message "gnomenm wifi disabled")
  55. (setq gnomenm/enabled nil))
  56. (defun gnomenm-status ()
  57. "What's the network status?"
  58. (interactive)
  59. (message "gnomenm network is %s"
  60. (if gnomenm/enabled "on" "off")))
  61. ;;;###autoload
  62. (defun gnomenm-toggle-enabled (&optional status)
  63. "Toggle whether WIFI is enabled or not."
  64. (interactive "P")
  65. (cond
  66. ((null status)
  67. (if gnomenm/enabled (gnomenm/disable) (gnomenm/enable)))
  68. ((> (prefix-numeric-value status) 0)
  69. (gnomenm/enable))
  70. ((< (prefix-numeric-value status) 1)
  71. (gnomenm/disable))))
  72. ;;;###autoload
  73. (defalias 'toggle-gnomenm-enabled 'gnomenm-toggle-enabled)
  74. (defun gnomenm/connected ()
  75. "What AP are we currently connected to?"
  76. (car
  77. (split-string
  78. (shell-command-to-string "nmcli -t -f name con show --active")
  79. "\n")))
  80. (defun gnomenm/list-aps ()
  81. "Make a list of all APs."
  82. (split-string
  83. (shell-command-to-string "nmcli -t -f name con")
  84. "\n"))
  85. (defun gnomenm/disconnect (ap)
  86. "Disconnect from the specified AP."
  87. (car
  88. (split-string
  89. (shell-command-to-string
  90. (format "nmcli -t -f name con down id \"%s\"" ap))
  91. "\n")))
  92. (defvar gnomenm/connect-history '()
  93. "History of all you have connected to.")
  94. (defun gnomenm/connect (ap)
  95. "Connect to the specified AP."
  96. (shell-command-to-string
  97. (format "nmcli -t -f name con up id \"%s\"" ap))
  98. (setq gnomenm/connect-history
  99. (append (list ap) gnomenm/connect-history)))
  100. ;;;###autoload
  101. (defun gnomenm-disconnect ()
  102. "Disconnect from the current Access Point."
  103. (interactive)
  104. (let ((current-ap (gnomenm/connected)))
  105. (gnomenm/disconnect current-ap)))
  106. (defvar gnomenm-connect-history nil
  107. "The history of APs you've connected to.")
  108. ;;;###autoload
  109. (defun gnomenm-connect (ap)
  110. "Connect to a specific AP."
  111. (interactive
  112. (list
  113. (let ((ap-list (gnomenm/list-aps)))
  114. (completing-read
  115. "What access point? " ap-list nil t
  116. (if gnomenm-connect-history
  117. (car gnomenm-connect-history)
  118. nil)
  119. 'gnomenm-connect-history))))
  120. (let ((current-ap (gnomenm/connected)))
  121. (if (equal ap current-ap)
  122. (message "nm: already connected to %s" ap)
  123. ;; Else let's try and connect to it
  124. (if (equal "802-11-wireless" (elt (kva ap (gnomenm/list)) 2))
  125. (unwind-protect
  126. (gnomenm/disconnect current-ap)
  127. (gnomenm/connect ap))
  128. ;; Else just connect
  129. (gnomenm/connect ap)))))
  130. ;;;###autoload
  131. (defun gnomenm-flip ()
  132. "Flip the AP to the last but one connected to.
  133. If you don't have two APs in the history it does nothing.
  134. This is really useful if you switch between a pair of APs like I
  135. do. I recommend using a keychord like:
  136. (key-chord-define-global \"90\" 'gnomenm-flip)
  137. See http://www.emacswiki.org/KeyChord for details on KeyChord."
  138. (interactive)
  139. (let* ((ap (gnomenm/connected))
  140. (new-ap
  141. (cl-loop for previous-ap in gnomenm/connect-history
  142. if (and previous-ap (not (equal ap previous-ap)))
  143. return previous-ap)))
  144. (when new-ap
  145. (gnomenm-connect new-ap))))
  146. (provide 'gnomenm)
  147. ;;; gnomenm.el ends here