vip.el 90 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987
  1. ;; VIP: A VI Package for GNU Emacs (version 2.7 of February 10, 1987)
  2. ;; Author: Masahiko Sato (ms@sail.stanford.edu). In Japan, the author's
  3. ;; address is: masahiko@nttlab.ntt.junet
  4. ;; Please send suggestions and bug reports to one of the above addresses.
  5. ;; Execute info command by typing "M-x info" to get information on VIP.
  6. ;; external variables
  7. (defvar emacs-local-map nil
  8. "Local map used in emacs mode. \(buffer specific\)")
  9. (defvar insert-local-map nil
  10. "Local map used in insert command mode. \(buffer specific\)")
  11. (make-variable-buffer-local 'emacs-local-map)
  12. (make-variable-buffer-local 'insert-local-map)
  13. (defvar insert-point nil
  14. "Remember insert point as a marker. \(buffer specific\)")
  15. (set-default 'insert-point (make-marker))
  16. (make-variable-buffer-local 'insert-point)
  17. (defvar com-point nil
  18. "Remember com point as a marker. \(buffer specific\)")
  19. (set-default 'com-point (make-marker))
  20. (make-variable-buffer-local 'com-point)
  21. (defvar current-mode nil
  22. "Current mode. One of emacs-mode, vi-mode, insert-mode.")
  23. (make-variable-buffer-local 'current-mode)
  24. (set-default 'current-mode 'emacs-mode)
  25. (defvar current-major-mode nil
  26. "current-major-mode is the major-mode vi considers it is now.
  27. \(buffer specific\)")
  28. (make-variable-buffer-local 'current-major-mode)
  29. (defvar vi-last-shell-com nil
  30. "last shell command executed by ! command")
  31. (defvar use-register nil
  32. "name of register to store deleted or yanked strings.")
  33. (defvar d-com nil
  34. "If non-nil, it's value is a list (M-COM VAL COM), and is used to
  35. re-execute last destrcutive command")
  36. (defconst shift-width 8
  37. "*The number of colums shifted by > and < command.")
  38. (defconst re-replace nil
  39. "*If t then do regexp replace, if nil then do string replace.")
  40. (defvar d-char nil
  41. "The character remenbered by the vi \"r\" command")
  42. (defvar f-char nil
  43. "for use by \";\" command")
  44. (defvar F-char nil
  45. "for use by \".\" command")
  46. (defvar f-forward nil
  47. "for use by \";\" command")
  48. (defvar f-offset nil
  49. "for use by \";\" command")
  50. (defconst vi-search-wrap-around t
  51. "*if t, search wraps around")
  52. (defconst re-search nil
  53. "*if t, search is reg-exp search, otherwise vanilla search.")
  54. (defvar s-string nil
  55. "last search string")
  56. (defvar s-forward nil
  57. "if t, search is forward.")
  58. (defconst vi-case-fold-search nil
  59. "*if t, search ignores cases.")
  60. (defconst re-query-replace nil
  61. "*If t then do regexp replace, if nil then do string replace.")
  62. (defconst vi-open-with-indent nil
  63. "*if t, indent when open a new line.")
  64. (defconst help-in-insert-mode nil
  65. "*if t then C-h is bound to help-command in insert mode, if nil then it is
  66. bound to delete-backward-char.")
  67. (defvar vi-quote-string "> "
  68. "string inserted at the beginning of region")
  69. (setq tags-file-name "TAGS")
  70. ;; basic set up
  71. (global-set-key "\C-z" 'change-mode-to-vi)
  72. (defmacro loop (count body)
  73. "(COUNT BODY) Execute BODY COUNT times."
  74. (list 'let (list (list 'count count))
  75. (list 'while (list '> 'count 0)
  76. body
  77. (list 'setq 'count (list '1- 'count)))))
  78. (defun push-mark-silent (&optional location)
  79. "Set mark at location (point, by default) and push old mark on mark ring.
  80. No message."
  81. (if (null (mark))
  82. nil
  83. (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
  84. (if (> (length mark-ring) mark-ring-max)
  85. (progn
  86. (move-marker (car (nthcdr mark-ring-max mark-ring)) nil)
  87. (setcdr (nthcdr (1- mark-ring-max) mark-ring) nil))))
  88. (set-mark (or location (point))))
  89. (defun vi-goto-col (arg)
  90. "(ARG) Go to ARG's column."
  91. (interactive "P")
  92. (let ((val (p-val arg))
  93. (com (getcom arg)))
  94. (save-excursion
  95. (end-of-line)
  96. (if (> val (1+ (current-column))) (error "")))
  97. (if com (move-marker com-point (point)))
  98. (beginning-of-line)
  99. (forward-char (1- val))
  100. (if com (execute-com 'vi-goto-col val com))))
  101. (defun refresh-mode-line ()
  102. "Redraw mode line."
  103. (set-buffer-modified-p (buffer-modified-p)))
  104. (defun vi-copy-keymap (map)
  105. (if (null map) (make-sparse-keymap) (copy-keymap map)))
  106. ;; changing mode
  107. (defun change-mode (new-mode)
  108. "(NEW-MODE) Change mode to NEW-MODE. NEW-MODE is either emacs-mode,
  109. vi-mode, or insert-mode."
  110. (or (eq new-mode current-mode)
  111. (progn
  112. (cond ((eq new-mode 'vi-mode)
  113. (if (eq current-mode 'insert-mode)
  114. (progn
  115. (vi-copy-region-as-kill (point) insert-point)
  116. (repeat-insert-command))
  117. (setq emacs-local-map (current-local-map)
  118. insert-local-map (vi-copy-keymap (current-local-map))))
  119. (change-mode-line "Vi: ")
  120. (use-local-map vi-command-mode-map))
  121. ((eq new-mode 'insert-mode)
  122. (move-marker insert-point (point))
  123. (if (eq current-mode 'emacs-mode)
  124. (setq emacs-local-map (current-local-map)
  125. insert-local-map
  126. (vi-copy-keymap (current-local-map))))
  127. (change-mode-line "Insert")
  128. (use-local-map insert-local-map)
  129. (define-key insert-local-map "\e" 'change-mode-to-vi)
  130. (define-key insert-local-map "\C-z" 'vi-ESC)
  131. (define-key insert-local-map "\C-h"
  132. (if help-in-insert-mode 'help-command 'delete-backward-char))
  133. (define-key insert-local-map "\C-w" 'delete-backward-word))
  134. ((eq new-mode 'emacs-mode)
  135. (change-mode-line "Emacs:")
  136. (use-local-map emacs-local-map)))
  137. (setq current-mode new-mode)
  138. (refresh-mode-line))))
  139. (defun vi-copy-region-as-kill (beg end)
  140. "(BEG END) If BEG and END do not belong to the same buffer, it copies
  141. empty region."
  142. (condition-case nil
  143. (copy-region-as-kill beg end)
  144. (error (copy-region-as-kill beg beg))))
  145. (defun change-mode-line (string)
  146. "Assuming that the mode line format contains the string \"Emacs:\", this
  147. function replaces the string by \"Vi: \" etc."
  148. (setq mode-line-buffer-identification
  149. (list (concat string " %17b"))))
  150. (defun vip-mode ()
  151. "Turn on VIP emulation of VI."
  152. (interactive)
  153. (change-mode-to-vi))
  154. (defun change-mode-to-vi ()
  155. "() Change mode to vi."
  156. (interactive)
  157. (change-mode 'vi-mode))
  158. (defun change-mode-to-insert ()
  159. "() Change mode to insert."
  160. (interactive)
  161. (change-mode 'insert-mode))
  162. (defun change-mode-to-emacs ()
  163. "() Change mode to emacs."
  164. (interactive)
  165. (change-mode 'emacs-mode))
  166. ;; escape to emacs mode termporarilly
  167. (defun get-editor-command (l-map g-map &optional str)
  168. "(L-MAP G-MAP STR) Read characters from keyboard until an editor command
  169. is formed, using local keymap L-MAP and global keymap G-MAP. If the
  170. command is a self-insert-command, the character just read is returned
  171. instead. Optional string STR is used as initial input string."
  172. (let (char l-bind g-bind)
  173. (setq char
  174. (if (or (null str) (string= str ""))
  175. (read-char)
  176. (string-to-char str)))
  177. (setq last-command-char char)
  178. (setq l-bind (binding-of char l-map))
  179. (if (null l-bind)
  180. ;; since local binding is empty, we concentrate on global one.
  181. (progn
  182. (setq g-bind (binding-of char g-map))
  183. (if (null g-bind)
  184. nil ;; return nil, since both bindings are void.
  185. (if (keymapp g-bind)
  186. (get-editor-command nil g-bind (string-tail str))
  187. (if (eq g-bind 'self-insert-command) char g-bind))))
  188. ;; local binding is nonvoid
  189. (if (keymapp l-bind)
  190. ;; since l-bind is a keymap, we consider g-bind as well.
  191. (progn
  192. (setq g-bind (binding-of char g-map))
  193. (if (null g-bind)
  194. (get-editor-command l-bind nil (string-tail str))
  195. (if (keymapp g-bind)
  196. ;; both bindings are keymap
  197. (get-editor-command l-bind g-bind (string-tail str))
  198. ;; l-bind is a keymap, so we neglect g-bind
  199. (get-editor-command l-bind nil (string-tail str)))))
  200. ;; l-bind is a command
  201. (if (eq l-bind 'self-insert-command) char l-bind)))))
  202. (defun binding-of (char map)
  203. "(CHAR MAP) Return key-binding of CHAR under keymap MAP. It is nil if
  204. the binding is void, or a command, or a keymap"
  205. (let ((val (if (listp map)
  206. (cdr (assq char map))
  207. (aref map char))))
  208. (cond ((null val) nil)
  209. ((keymapp val)
  210. (if (symbolp val) (symbol-function val) val))
  211. (t
  212. ;; otherwise, it is a function which is either a real function or
  213. ;; a keymap fset to val.
  214. (let ((fun (symbol-function val)))
  215. (if (or (null fun) (keymapp fun)) fun val))))))
  216. (defun escape-to-emacs (arg &optional char)
  217. "(ARG &optional CHAR) Escape to emacs mode and execute one emacs
  218. command and then return to vi mode. ARG is used as the prefix value
  219. for the executed command. If CHAR is given it becomes the first
  220. character of the command."
  221. (interactive "P")
  222. (let (com (buff (current-buffer)) (first t))
  223. (if char (setq unread-command-char char))
  224. (setq prefix-arg arg)
  225. (while (or first (>= unread-command-char 0))
  226. ;; this while loop is executed until unread command char will be
  227. ;; exhausted.
  228. (setq first nil)
  229. (setq com (get-editor-command emacs-local-map global-map))
  230. (if (numberp com)
  231. (loop (p-val prefix-arg) (insert-string (char-to-string com)))
  232. (command-execute com prefix-arg)))
  233. (setq prefix-arg nil) ;; reset prefix arg
  234. ))
  235. (defun message-conditions (conditions)
  236. "Print conditions as a message."
  237. (let ((case (car conditions)) (msg (cdr conditions)))
  238. (if (null msg)
  239. (message "%s" case)
  240. (message "%s %s" case (prin1-to-string msg)))
  241. (ding)))
  242. (defun vi-ESC (arg) ""
  243. (interactive "P")
  244. (escape-to-emacs arg ?\e))
  245. (defun vi-ctl-c (arg) ""
  246. (interactive "P")
  247. (escape-to-emacs arg ?\C-c))
  248. (defun vi-ctl-x (arg) ""
  249. (interactive "P")
  250. (escape-to-emacs arg ?\C-x))
  251. (defun vi-ctl-h (arg) ""
  252. (interactive "P")
  253. (escape-to-emacs arg ?\C-h))
  254. ;; prefix argmument for vi mode
  255. ;; In vi mode, prefix argument is a dotted pair (NUM . COM) where NUM
  256. ;; represents the numeric value of the prefix argument and COM represents
  257. ;; command prefix such as "c", "d", "m" and "y".
  258. (defun vi-prefix-arg-value (char value com)
  259. "(CHAR VALUE COM) Compute numeric prefix arg value. Invoked by
  260. CHAR. VALUE is the value obtained so far, and COM is the command part
  261. obtained so far."
  262. (while (and (>= char ?0) (<= char ?9))
  263. (setq value (+ (* (if (numberp value) value 0) 10) (- char ?0)))
  264. (setq char (read-char)))
  265. (setq prefix-arg value)
  266. (if com (setq prefix-arg (cons prefix-arg com)))
  267. (while (= char ?U)
  268. (describe-arg prefix-arg)
  269. (setq char (read-char)))
  270. (setq unread-command-char char))
  271. (defun vi-prefix-arg-com (char value com)
  272. "Vi operator as prefix argument."
  273. (let ((cont t))
  274. (while (and cont
  275. (or (= char ?c) (= char ?d) (= char ?y)
  276. (= char ?!) (= char ?<) (= char ?>) (= char ?=)
  277. (= char ?#) (= char ?r) (= char ?R) (= char ?\")))
  278. (if com
  279. ;; this means that we already have a command character, so we
  280. ;; construct a com list and exit while. however, if char is "
  281. ;; it is an error.
  282. (progn
  283. ;; new com is (CHAR . OLDCOM)
  284. (if (or (= char ?#) (= char ?\")) (error ""))
  285. (setq com (cons char com))
  286. (setq cont nil))
  287. ;; if com is nil we set com as char, and read more. again, if char
  288. ;; is ", we read the name of register and store it in use-register.
  289. ;; if char is !, =, or #, a copmlete com is formed so we exit while.
  290. (cond ((or (= char ?!) (= char ?=))
  291. (setq com char)
  292. (setq char (read-char))
  293. (setq cont nil))
  294. ((= char ?#)
  295. ;; read a char and encode it as com
  296. (setq com (+ 128 (read-char)))
  297. (setq char (read-char))
  298. (setq cont nil))
  299. ((or (= char ?<) (= char ?>))
  300. (setq com char)
  301. (setq char (read-char))
  302. (if (= com char) (setq com (cons char com)))
  303. (setq cont nil))
  304. ((= char ?\")
  305. (let ((reg (read-char)))
  306. (if (or (and (<= ?A reg) (<= reg ?z))
  307. (and (<= ?1 reg) (<= reg ?9)))
  308. (setq use-register reg)
  309. (error ""))
  310. (setq char (read-char))))
  311. (t
  312. (setq com char)
  313. (setq char (read-char)))))))
  314. (if (atom com)
  315. ;; com is a single char, so we construct prefix-arg
  316. ;; and if char is ?, describe prefix arg, otherwise exit by
  317. ;; pushing the char back
  318. (progn
  319. (setq prefix-arg (cons value com))
  320. (while (= char ?U)
  321. (describe-arg prefix-arg)
  322. (setq char (read-char)))
  323. (setq unread-command-char char))
  324. ;; as com is non-nil, this means that we have a command to execute
  325. (if (or (= (car com) ?r) (= (car com) ?R))
  326. ;; execute apropriate region command.
  327. (let ((char (car com)) (com (cdr com)))
  328. (setq prefix-arg (cons value com))
  329. (if (= char ?r) (vi-region prefix-arg)
  330. (vi-Region prefix-arg))
  331. ;; reset prefix-arg
  332. (setq prefix-arg nil))
  333. ;; otherwise, reset prefix arg and call appropriate command
  334. (setq value (if (null value) 1 value))
  335. (setq prefix-arg nil)
  336. (cond ((equal com '(?c . ?c)) (vi-line (cons value ?C)))
  337. ((equal com '(?d . ?d)) (vi-line (cons value ?D)))
  338. ((equal com '(?d . ?y)) (vi-yank-defun))
  339. ((equal com '(?y . ?y)) (vi-line (cons value ?Y)))
  340. ((equal com '(?< . ?<)) (vi-line (cons value ?<)))
  341. ((equal com '(?> . ?>)) (vi-line (cons value ?>)))
  342. ((equal com '(?! . ?!)) (vi-line (cons value ?!)))
  343. ((equal com '(?= . ?=)) (vi-line (cons value ?=)))
  344. (t (error ""))))))
  345. (defun describe-arg (arg)
  346. (let (val com)
  347. (setq val (P-val arg)
  348. com (getcom arg))
  349. (if (null val)
  350. (if (null com)
  351. (message "Value is nil, and commmand is nil.")
  352. (message "Value is nil, and command is %c." com))
  353. (if (null com)
  354. (message "Value is %d, and command is nil." val)
  355. (message "Value is %d, and command is %c." val com)))))
  356. (defun vi-digit-argument (arg)
  357. "Begin numeric argument for the next command."
  358. (interactive "P")
  359. (vi-prefix-arg-value last-command-char nil
  360. (if (consp arg) (cdr arg) nil)))
  361. (defun vi-command-argument (arg)
  362. (interactive "P")
  363. (condition-case conditions
  364. (vi-prefix-arg-com
  365. last-command-char
  366. (cond ((null arg) nil)
  367. ((consp arg) (car arg))
  368. ((numberp arg) arg)
  369. (t (error "strange arg")))
  370. (cond ((null arg) nil)
  371. ((consp arg) (cdr arg))
  372. ((numberp arg) nil)
  373. (t (error "strange arg"))))
  374. (quit
  375. (setq use-register nil)
  376. (signal 'quit nil))))
  377. (defun p-val (arg)
  378. "(ARG) Get value part of prefix-argument ARG."
  379. (cond ((null arg) 1)
  380. ((consp arg) (if (null (car arg)) 1 (car arg)))
  381. (t arg)))
  382. (defun P-val (arg)
  383. "(ARG) Get value part of prefix-argument ARG."
  384. (cond ((consp arg) (car arg))
  385. (t arg)))
  386. (defun getcom (arg)
  387. "(ARG) Get com part of prefix-argument ARG."
  388. (cond ((null arg) nil)
  389. ((consp arg) (cdr arg))
  390. (t nil)))
  391. (defun getCom (arg)
  392. "(ARG) Get com part of prefix-argument ARG and modify it."
  393. (let ((com (getcom arg)))
  394. (cond ((equal com ?c) ?C)
  395. ((equal com ?d) ?D)
  396. ((equal com ?y) ?Y)
  397. (t com))))
  398. ;; repeat last destructive command
  399. (defun vi-append-to-register (reg start end)
  400. "Append region to text in register REG.
  401. START and END are buffer positions indicating what to append."
  402. (set-register reg (concat (or (get-register reg) "")
  403. (buffer-substring start end))))
  404. (defun execute-com (m-com val com)
  405. "(M-COM VAL COM) Execute command COM. The list (M-COM VAL COM) is set
  406. to d-com for later use by vi-repeat"
  407. (let ((reg use-register))
  408. (if com
  409. (cond ((= com ?c) (vi-change com-point (point)))
  410. ((= com (- ?c)) (vi-change-subr com-point (point)))
  411. ((or (= com ?C) (= com (- ?C)))
  412. (save-excursion
  413. (set-mark com-point)
  414. (enlarge-region (mark) (point))
  415. (if use-register
  416. (progn
  417. (cond ((and (<= ?a use-register) (<= use-register ?z))
  418. (copy-to-register
  419. use-register (mark) (point) nil))
  420. ((and (<= ?A use-register) (<= use-register ?Z))
  421. (vi-append-to-register
  422. (+ use-register 32) (mark) (point)))
  423. (t (setq use-register nil)
  424. (error "")))
  425. (setq use-register nil)))
  426. (delete-region (mark) (point)))
  427. (open-line 1)
  428. (if (= com ?C) (change-mode-to-insert) (yank)))
  429. ((= com ?d)
  430. (if use-register
  431. (progn
  432. (cond ((and (<= ?a use-register) (<= use-register ?z))
  433. (copy-to-register
  434. use-register com-point (point) nil))
  435. ((and (<= ?A use-register) (<= use-register ?Z))
  436. (vi-append-to-register
  437. (+ use-register 32) com-point (point)))
  438. (t (setq use-register nil)
  439. (error "")))
  440. (setq use-register nil)))
  441. (setq last-command
  442. (if (eq last-command 'd-command) 'kill-region nil))
  443. (kill-region com-point (point))
  444. (setq this-command 'd-command))
  445. ((= com ?D)
  446. (save-excursion
  447. (set-mark com-point)
  448. (enlarge-region (mark) (point))
  449. (if use-register
  450. (progn
  451. (cond ((and (<= ?a use-register) (<= use-register ?z))
  452. (copy-to-register
  453. use-register (mark) (point) nil))
  454. ((and (<= ?A use-register) (<= use-register ?Z))
  455. (vi-append-to-register
  456. (+ use-register 32) (mark) (point)))
  457. (t (setq use-register nil)
  458. (error "")))
  459. (setq use-register nil)))
  460. (setq last-command
  461. (if (eq last-command 'D-command) 'kill-region nil))
  462. (kill-region (mark) (point))
  463. (if (eq m-com 'vi-line) (setq this-command 'D-command)))
  464. (back-to-indentation))
  465. ((= com ?y)
  466. (if use-register
  467. (progn
  468. (cond ((and (<= ?a use-register) (<= use-register ?z))
  469. (copy-to-register
  470. use-register com-point (point) nil))
  471. ((and (<= ?A use-register) (<= use-register ?Z))
  472. (vi-append-to-register
  473. (+ use-register 32) com-point (point)))
  474. (t (setq use-register nil)
  475. (error "")))
  476. (setq use-register nil)))
  477. (setq last-command nil)
  478. (copy-region-as-kill com-point (point))
  479. (goto-char com-point))
  480. ((= com ?Y)
  481. (save-excursion
  482. (set-mark com-point)
  483. (enlarge-region (mark) (point))
  484. (if use-register
  485. (progn
  486. (cond ((and (<= ?a use-register) (<= use-register ?z))
  487. (copy-to-register
  488. use-register (mark) (point) nil))
  489. ((and (<= ?A use-register) (<= use-register ?Z))
  490. (vi-append-to-register
  491. (+ use-register 32) (mark) (point)))
  492. (t (setq use-register nil)
  493. (error "")))
  494. (setq use-register nil)))
  495. (setq last-command nil)
  496. (copy-region-as-kill (mark) (point)))
  497. (goto-char com-point))
  498. ((or (= com ?!) (= com (- ?!)))
  499. (save-excursion
  500. (set-mark com-point)
  501. (enlarge-region (mark) (point))
  502. (shell-command-on-region
  503. (mark) (point)
  504. (if (= com ?!)
  505. (setq vi-last-shell-com (vi-read-string "!"))
  506. vi-last-shell-com)
  507. t)))
  508. ((= com ?=)
  509. (save-excursion
  510. (set-mark com-point)
  511. (enlarge-region (mark) (point))
  512. (if (> (mark) (point)) (exchange-point-and-mark))
  513. (indent-region (mark) (point) nil)))
  514. ((= com ?<)
  515. (save-excursion
  516. (set-mark com-point)
  517. (enlarge-region (mark) (point))
  518. (indent-rigidly (mark) (point) (- shift-width)))
  519. (goto-char com-point))
  520. ((= com ?>)
  521. (save-excursion
  522. (set-mark com-point)
  523. (enlarge-region (mark) (point))
  524. (indent-rigidly (mark) (point) shift-width))
  525. (goto-char com-point))
  526. ((>= com 128)
  527. ;; this is special command #
  528. (special-prefix-com (- com 128)))))
  529. (setq d-com (list m-com val (if (or (= com ?c) (= com ?C) (= com ?!))
  530. (- com) com)
  531. reg))))
  532. (defun vi-repeat (arg)
  533. "(ARG) Re-excute last destructive command. d-com has the form
  534. (COM ARG CH REG), where COM is the command to be re-executed, ARG is the
  535. argument for COM, CH is a flag for repeat, and REG is optional and if exists
  536. is the name of the register for COM."
  537. (interactive "P")
  538. (if (eq last-command 'vi-undo)
  539. ;; if the last command was vi-undo, then undo-more
  540. (vi-undo-more)
  541. ;; otherwise execute the command stored in d-com. if arg is non-nil
  542. ;; its prefix value is used as new prefix value for the command.
  543. (let ((m-com (car d-com))
  544. (val (P-val arg))
  545. (com (car (cdr (cdr d-com))))
  546. (reg (nth 3 d-com)))
  547. (if (null val) (setq val (car (cdr d-com))))
  548. (if (null m-com) (error "No previous command to repeat."))
  549. (setq use-register reg)
  550. (funcall m-com (cons val com)))))
  551. (defun special-prefix-com (char)
  552. "This command is invoked interactively by the key sequence #<char>"
  553. (cond ((= char ?c)
  554. (downcase-region (min com-point (point)) (max com-point (point))))
  555. ((= char ?C)
  556. (upcase-region (min com-point (point)) (max com-point (point))))
  557. ((= char ?g)
  558. (set-mark com-point)
  559. (global-execute))
  560. ((= char ?q)
  561. (set-mark com-point)
  562. (quote-region))
  563. ((= char ?s) (spell-region com-point (point)))))
  564. ;; undoing
  565. (defun vi-undo () ""
  566. (interactive)
  567. (message "undo!")
  568. (undo-start)
  569. (undo-more 2)
  570. (setq this-command 'vi-undo))
  571. (defun vi-undo-more () ""
  572. (message "undo more!")
  573. (undo-more 1)
  574. (setq this-command 'vi-undo))
  575. ;; utilities
  576. (defun string-tail (str)
  577. (if (or (null str) (string= str "")) nil
  578. (substring str 1)))
  579. (defun vi-yank-defun ()
  580. (mark-defun)
  581. (copy-region-as-kill (point) (mark)))
  582. (defun enlarge-region (beg end)
  583. "(BEG END) Enlarge region between BEG and END."
  584. (if (< beg end)
  585. (progn (goto-char beg) (set-mark end))
  586. (goto-char end)
  587. (set-mark beg))
  588. (beginning-of-line)
  589. (exchange-point-and-mark)
  590. (if (or (not (eobp)) (not (bolp))) (next-line 1))
  591. (beginning-of-line)
  592. (if (> beg end) (exchange-point-and-mark)))
  593. (defun global-execute ()
  594. "Call last keyboad macro for each line in the region."
  595. (if (> (point) (mark)) (exchange-point-and-mark))
  596. (beginning-of-line)
  597. (call-last-kbd-macro)
  598. (while (< (point) (mark))
  599. (forward-line 1)
  600. (beginning-of-line)
  601. (call-last-kbd-macro)))
  602. (defun quote-region ()
  603. "Quote region by inserting the user supplied string at the beginning of
  604. each line in the region."
  605. (setq vi-quote-string
  606. (let ((str
  607. (vi-read-string (format "quote string \(default \"%s\"\): "
  608. vi-quote-string))))
  609. (if (string= str "") vi-quote-string str)))
  610. (enlarge-region (point) (mark))
  611. (if (> (point) (mark)) (exchange-point-and-mark))
  612. (insert-string vi-quote-string)
  613. (beginning-of-line)
  614. (forward-line 1)
  615. (while (and (< (point) (mark)) (bolp))
  616. (insert-string vi-quote-string)
  617. (beginning-of-line)
  618. (forward-line 1)))
  619. (defun end-with-a-newline-p (string)
  620. "Check if the string ends with a newline."
  621. (or (string= text "")
  622. (= (aref string (1- (length string))) ?\n)))
  623. (defun vi-read-string (prompt &optional init)
  624. (setq save-minibuffer-local-map (copy-keymap minibuffer-local-map))
  625. (define-key minibuffer-local-map "\C-h" 'backward-char)
  626. (define-key minibuffer-local-map "\C-w" 'backward-word)
  627. (define-key minibuffer-local-map "\e" 'exit-minibuffer)
  628. (let (str)
  629. (condition-case conditions
  630. (setq str (read-string prompt init))
  631. (quit
  632. (setq minibuffer-local-map save-minibuffer-local-map)
  633. (signal 'quit nil)))
  634. (setq minibuffer-local-map save-minibuffer-local-map)
  635. str))
  636. ;; insertion commands
  637. (defun repeat-insert-command ()
  638. "() This function is called when mode changes from insertion mode to
  639. vi command mode. It will repeat the insertion command if original insertion
  640. command was invoked with argument > 1."
  641. (let ((i-com (car d-com)) (val (car (cdr d-com))))
  642. (if (and val (> val 1)) ;; first check that val is non-nil
  643. (progn
  644. (setq d-com (list i-com (1- val) ?r))
  645. (vi-repeat nil)
  646. (setq d-com (list i-com val ?r))))))
  647. (defun vi-insert (arg) ""
  648. (interactive "P")
  649. (let ((val (p-val arg)) (com (getcom arg)))
  650. (setq d-com (list 'vi-insert val ?r))
  651. (if com (loop val (yank))
  652. (change-mode-to-insert))))
  653. (defun vi-append (arg) ""
  654. (interactive "P")
  655. (let ((val (p-val arg)) (com (getcom arg)))
  656. (setq d-com (list 'vi-append val ?r))
  657. (if (not (eolp)) (forward-char))
  658. (if (equal com ?r)
  659. (loop val (yank))
  660. (change-mode-to-insert))))
  661. (defun vi-Append (arg) ""
  662. (interactive "P")
  663. (let ((val (p-val arg)) (com (getcom arg)))
  664. (setq d-com (list 'vi-Append val ?r))
  665. (end-of-line)
  666. (if (equal com ?r)
  667. (loop val (yank))
  668. (change-mode-to-insert))))
  669. (defun vi-Insert (arg) ""
  670. (interactive "P")
  671. (let ((val (p-val arg)) (com (getcom arg)))
  672. (setq d-com (list 'vi-Insert val ?r))
  673. (back-to-indentation)
  674. (if (equal com ?r)
  675. (loop val (yank))
  676. (change-mode-to-insert))))
  677. (defun vi-open-line (arg) ""
  678. (interactive "P")
  679. (let ((val (p-val arg)) (com (getcom arg)))
  680. (setq d-com (list 'vi-open-line val ?r))
  681. (let ((col (current-indentation)))
  682. (if (equal com ?r)
  683. (loop val
  684. (progn
  685. (end-of-line)
  686. (newline 1)
  687. (if vi-open-with-indent (indent-to col))
  688. (yank)))
  689. (end-of-line)
  690. (newline 1)
  691. (if vi-open-with-indent (indent-to col))
  692. (change-mode-to-insert)))))
  693. (defun vi-Open-line (arg) ""
  694. (interactive "P")
  695. (let ((val (p-val arg)) (com (getcom arg)))
  696. (setq d-com (list 'vi-Open-line val ?r))
  697. (let ((col (current-indentation)))
  698. (if (equal com ?r)
  699. (loop val
  700. (progn
  701. (beginning-of-line)
  702. (open-line 1)
  703. (if vi-open-with-indent (indent-to col))
  704. (yank)))
  705. (beginning-of-line)
  706. (open-line 1)
  707. (if vi-open-with-indent (indent-to col))
  708. (change-mode-to-insert)))))
  709. (defun vi-ctl-open-line (arg)
  710. (interactive "P")
  711. (let ((val (p-val arg)) (com (getcom arg)))
  712. (setq d-com (list 'vi-ctl-open-line val ?r))
  713. (if (equal com ?r)
  714. (loop val
  715. (progn
  716. (open-line 1)
  717. (yank)))
  718. (open-line 1)
  719. (change-mode-to-insert))))
  720. (defun vi-substitute (arg)
  721. (interactive "P")
  722. (let ((val (p-val arg)) (com (getcom arg)))
  723. (save-excursion
  724. (set-mark (point))
  725. (forward-char val)
  726. (if (equal com ?r)
  727. (vi-change-subr (mark) (point))
  728. (vi-change (mark) (point))))
  729. (setq d-com (list 'vi-substitute val ?r))))
  730. (defun vi-substitute-line (arg)
  731. (interactive "p")
  732. (vi-line (cons arg ?C)))
  733. ;; line command
  734. (defun vi-line (arg)
  735. (let ((val (car arg)) (com (cdr arg)))
  736. (move-marker com-point (point))
  737. (next-line (1- val))
  738. (execute-com 'vi-line val com)))
  739. (defun vi-yank-line (arg)
  740. "(ARG) Yank ARG lines (in vi's sense)"
  741. (interactive "P")
  742. (let ((val (p-val arg)))
  743. (vi-line (cons val ?Y))))
  744. ;; region command
  745. (defun vi-region (arg)
  746. (interactive "P")
  747. (let ((val (P-val arg))
  748. (com (getcom arg)))
  749. (move-marker com-point (point))
  750. (exchange-point-and-mark)
  751. (execute-com 'vi-region val com)))
  752. (defun vi-Region (arg)
  753. (interactive "P")
  754. (let ((val (P-val arg))
  755. (com (getCom arg)))
  756. (move-marker com-point (point))
  757. (exchange-point-and-mark)
  758. (execute-com 'vi-Region val com)))
  759. (defun vi-replace-char (arg)
  760. "(ARG) Replace the following ARG chars by the character read."
  761. (interactive "P")
  762. (let ((val (p-val arg)) (com (getcom arg)))
  763. (setq d-com (list 'vi-replace-char val ?r))
  764. (vi-replace-char-subr (if (equal com ?r) d-char (read-char)) val)))
  765. (defun vi-replace-char-subr (char arg)
  766. (delete-char arg t)
  767. (setq d-char char)
  768. (loop (if (> arg 0) arg (- arg)) (insert char))
  769. (backward-char arg))
  770. (defun vi-replace-string ()
  771. "() Replace string. If you supply null string as the string to be
  772. replaced, the query replace mode will toggle between string replace
  773. and regexp replace."
  774. (interactive)
  775. (let (str)
  776. (setq str (vi-read-string
  777. (if re-replace "Replace regexp: " "Replace string: ")))
  778. (if (string= str "")
  779. (progn
  780. (setq re-replace (not re-replace))
  781. (message (format "Replace mode changed to %s."
  782. (if re-replace "regexp replace" "string replace"))))
  783. (if re-replace
  784. (replace-regexp
  785. str
  786. (vi-read-string (format "Replace regexp \"%s\" with: " str)))
  787. (replace-string
  788. str
  789. (vi-read-string (format "Replace \"%s\" with: " str)))))))
  790. ;; basic cursor movement. j, k, l, m commands.
  791. (defun vi-forward-char (arg)
  792. "(ARG) Move point right ARG characters (left if ARG negative).
  793. On reaching end of buffer, stop and signal error."
  794. (interactive "P")
  795. (let ((val (p-val arg)) (com (getcom arg)))
  796. (if com (move-marker com-point (point)))
  797. (forward-char val)
  798. (if com (execute-com 'vi-forward-char val com))))
  799. (defun vi-backward-char (arg)
  800. "(ARG) Move point left ARG characters (right if ARG negative).
  801. On reaching beginning of buffer, stop and signal error."
  802. (interactive "P")
  803. (let ((val (p-val arg)) (com (getcom arg)))
  804. (if com (move-marker com-point (point)))
  805. (backward-char val)
  806. (if com (execute-com 'vi-backward-char val com))))
  807. ;; word command
  808. (defun vi-forward-word (arg) ""
  809. (interactive "P")
  810. (let ((val (p-val arg))
  811. (com (getcom arg)))
  812. (if com (move-marker com-point (point)))
  813. (forward-word val)
  814. (skip-chars-forward " \t\n")
  815. (if com
  816. (progn
  817. (if (or (= com ?c) (= com (- ?c)))
  818. (progn (backward-word 1) (forward-word 1)))
  819. (if (or (= com ?d) (= com ?y))
  820. (progn
  821. (backward-word 1)
  822. (forward-word 1)
  823. (skip-chars-forward " \t")))
  824. (execute-com 'vi-forward-word val com)))))
  825. (defun vi-end-of-word (arg)
  826. "move point to end of current word"
  827. (interactive "P")
  828. (let ((val (p-val arg))
  829. (com (getcom arg)))
  830. (if com (move-marker com-point (point)))
  831. (forward-char)
  832. (forward-word val)
  833. (backward-char)
  834. (if com
  835. (progn
  836. (forward-char)
  837. (execute-com 'vi-end-of-word val com)))))
  838. (defun vi-backward-word (arg) ""
  839. (interactive "P")
  840. (let ((val (p-val arg))
  841. (com (getcom arg)))
  842. (if com (move-marker com-point (point)))
  843. (backward-word val)
  844. (if com (execute-com 'vi-backward-word val com))))
  845. (defun vi-forward-Word (arg) ""
  846. (interactive "P")
  847. (let ((val (p-val arg))
  848. (com (getcom arg)))
  849. (if com (move-marker com-point (point)))
  850. (re-search-forward "[^ \t\n]*[ \t\n]+" nil t val)
  851. (if com
  852. (progn
  853. (if (or (= com ?c) (= com (- ?c)))
  854. (progn (backward-word 1) (forward-word 1)))
  855. (if (or (= com ?d) (= com ?y))
  856. (progn
  857. (backward-word 1)
  858. (forward-word 1)
  859. (skip-chars-forward " \t")))
  860. (execute-com 'vi-forward-Word val com)))))
  861. (defun vi-end-of-Word (arg) ""
  862. (interactive "P")
  863. (let ((val (p-val arg))
  864. (com (getcom arg)))
  865. (if com (move-marker com-point (point)))
  866. (forward-char)
  867. (if (re-search-forward "[^ \t\n]+" nil t val) (backward-char))
  868. (if com
  869. (progn
  870. (forward-char)
  871. (execute-com 'vi-end-of-Word val com)))))
  872. (defun vi-backward-Word (arg) ""
  873. (interactive "P")
  874. (let ((val (p-val arg))
  875. (com (getcom arg)))
  876. (if com (move-marker com-point (point)))
  877. (if (re-search-backward "[ \t\n]+[^ \t\n]+" nil t val)
  878. (forward-char)
  879. (goto-char (point-min)))
  880. (if com (execute-com 'vi-backward-Word val com))))
  881. (defun vi-beginning-of-line (arg)
  882. (interactive "P")
  883. (let ((val (p-val arg)) (com (getcom arg)))
  884. (if com (move-marker com-point (point)))
  885. (beginning-of-line val)
  886. (if com (execute-com 'vi-beginning-of-line val com))))
  887. (defun vi-bol-and-skip-white (arg)
  888. (interactive "P")
  889. (let ((val (p-val arg)) (com (getcom arg)))
  890. (if com (move-marker com-point (point)))
  891. (back-to-indentation)
  892. (if com (execute-com 'vi-bol-and-skip-white val com))))
  893. (defun vi-goto-eol (arg)
  894. (interactive "P")
  895. (let ((val (p-val arg)) (com (getcom arg)))
  896. (if com (move-marker com-point (point)))
  897. (end-of-line val)
  898. (if com (execute-com 'vi-goto-eol val com))))
  899. (defun vi-next-line (arg)
  900. (interactive "P")
  901. (let ((val (p-val arg)) (com (getCom arg)))
  902. (if com (move-marker com-point (point)))
  903. (next-line val)
  904. (setq this-command 'next-line)
  905. (if com (execute-com 'vi-next-line val com))))
  906. (defun vi-next-line-at-bol (arg)
  907. (interactive "P")
  908. (let ((val (p-val arg)) (com (getCom arg)))
  909. (if com (move-marker com-point (point)))
  910. (next-line val)
  911. (back-to-indentation)
  912. (if com (execute-com 'vi-next-line-at-bol val com))))
  913. (defun vi-previous-line (arg)
  914. (interactive "P")
  915. (let ((val (p-val arg)) (com (getCom arg)))
  916. (if com (move-marker com-point (point)))
  917. (next-line (- val))
  918. (setq this-command 'previous-line)
  919. (if com (execute-com 'vi-previous-line val com))))
  920. (defun vi-previous-line-at-bol (arg)
  921. (interactive "P")
  922. (let ((val (p-val arg)) (com (getCom arg)))
  923. (if com (move-marker com-point (point)))
  924. (next-line (- val))
  925. (back-to-indentation)
  926. (if com (execute-com 'vi-previous-line val com))))
  927. (defun vi-change-to-eol (arg)
  928. (interactive "P")
  929. (vi-goto-eol (cons arg ?c)))
  930. (defun vi-kill-line (arg)
  931. (interactive "P")
  932. (vi-goto-eol (cons arg ?d)))
  933. ;; moving around
  934. (defun vi-goto-line (arg)
  935. (interactive "P")
  936. (let ((val (P-val arg)) (com (getCom arg)))
  937. (move-marker com-point (point))
  938. (set-mark (point))
  939. (if (null val)
  940. (goto-char (point-max))
  941. (goto-char (point-min))
  942. (forward-line (1- val)))
  943. (back-to-indentation)
  944. (if com (execute-com 'vi-goto-line val com))))
  945. (defun vi-find-char (arg char forward offset)
  946. "(ARG CHAR FORWARD OFFSET) Find ARG's occurence of CHAR on the
  947. current line. If FORWARD then search is forward, otherwise backward.
  948. OFFSET is used to adjust point after search."
  949. (let ((arg (if forward arg (- arg))) point)
  950. (save-excursion
  951. (save-restriction
  952. (if (> arg 0)
  953. (narrow-to-region
  954. ;; forward search begins here
  955. (if (eolp) (error "") (point))
  956. ;; forward search ends here
  957. (progn (next-line 1) (beginning-of-line) (point)))
  958. (narrow-to-region
  959. ;; backward search begins from here
  960. (if (bolp) (error "") (point))
  961. ;; backward search ends here
  962. (progn (beginning-of-line) (point))))
  963. ;; if arg > 0, point is forwarded before search.
  964. (if (> arg 0) (goto-char (1+ (point-min)))
  965. (goto-char (point-max)))
  966. (setq point (scan-buffer (point) arg char))
  967. (if (or (and (> arg 0) (= point (point-max)))
  968. (and (< arg 0) (= point (point-min))))
  969. (error ""))))
  970. (goto-char (+ point (if offset (if (> arg 0) -2 0) -1)))))
  971. (defun vi-find-char-forward (arg)
  972. "(ARG) Find char on the line. If called interactively read the char
  973. to find from the terminal, and if called from vi-repeat, the char
  974. last used is used. This behaviour is controlled by the sign of prefix
  975. numeric value."
  976. (interactive "P")
  977. (let ((val (p-val arg)) (com (getcom arg)))
  978. (if (> val 0)
  979. ;; this means that the function was called interactively
  980. (setq f-char (read-char)
  981. f-forward t
  982. f-offset nil)
  983. (setq val (- val)))
  984. (if com (move-marker com-point (point)))
  985. (vi-find-char val (if (> (p-val arg) 0) f-char F-char) t nil)
  986. (setq val (- val))
  987. (if com
  988. (progn
  989. (setq F-char f-char);; remember new F-char
  990. (forward-char)
  991. (execute-com 'vi-find-char-forward val com)))))
  992. (defun vi-goto-char-forward (arg) ""
  993. (interactive "P")
  994. (let ((val (p-val arg)) (com (getcom arg)))
  995. (if (> val 0)
  996. ;; this means that the function was called interactively
  997. (setq f-char (read-char)
  998. f-forward t
  999. f-offset t)
  1000. (setq val (- val)))
  1001. (if com (move-marker com-point (point)))
  1002. (vi-find-char val (if (> (p-val arg) 0) f-char F-char) t t)
  1003. (setq val (- val))
  1004. (if com
  1005. (progn
  1006. (setq F-char f-char);; remember new F-char
  1007. (forward-char)
  1008. (execute-com 'vi-goto-char-forward val com)))))
  1009. (defun vi-find-char-backward (arg) ""
  1010. (interactive "P")
  1011. (let ((val (p-val arg)) (com (getcom arg)))
  1012. (if (> val 0)
  1013. ;; this means that the function was called interactively
  1014. (setq f-char (read-char)
  1015. f-forward nil
  1016. f-offset nil)
  1017. (setq val (- val)))
  1018. (if com (move-marker com-point (point)))
  1019. (vi-find-char val (if (> (p-val arg) 0) f-char F-char) nil nil)
  1020. (setq val (- val))
  1021. (if com
  1022. (progn
  1023. (setq F-char f-char);; remember new F-char
  1024. (execute-com 'vi-find-char-backward val com)))))
  1025. (defun vi-goto-char-backward (arg) ""
  1026. (interactive "P")
  1027. (let ((val (p-val arg)) (com (getcom arg)))
  1028. (if (> val 0)
  1029. ;; this means that the function was called interactively
  1030. (setq f-char (read-char)
  1031. f-forward nil
  1032. f-offset t)
  1033. (setq val (- val)))
  1034. (if com (move-marker com-point (point)))
  1035. (vi-find-char val (if (> (p-val arg) 0) f-char F-char) nil t)
  1036. (setq val (- val))
  1037. (if com
  1038. (progn
  1039. (setq F-char f-char);; remember new F-char
  1040. (execute-com 'vi-goto-char-backward val com)))))
  1041. (defun vi-semi-colon (arg) ""
  1042. (interactive "P")
  1043. (let ((val (p-val arg)) (com (getcom arg)))
  1044. (if com (move-marker com-point (point)))
  1045. (vi-find-char val f-char f-forward f-offset)
  1046. (if com
  1047. (progn
  1048. (if f-forward (forward-char))
  1049. (execute-com 'vi-semi-colon val com)))))
  1050. (defun vi-comma (arg) ""
  1051. (interactive "P")
  1052. (let ((val (p-val arg)) (com (getcom arg)))
  1053. (if com (move-marker com-point (point)))
  1054. (vi-find-char val f-char (not f-forward) f-offset)
  1055. (if com
  1056. (progn
  1057. (if f-forward (forward-char))
  1058. (execute-com 'vi-comma val com)))))
  1059. ;; window scrolling etc.
  1060. (defun vi-other-window (arg)
  1061. (interactive "p")
  1062. (other-window arg)
  1063. (or (not (eq current-mode 'emacs-mode))
  1064. (string= (buffer-name (current-buffer)) " *Minibuf-1*")
  1065. (change-mode-to-vi)))
  1066. (defun vi-window-top (arg) ""
  1067. (interactive "P")
  1068. (let ((val (p-val arg))
  1069. (com (getCom arg)))
  1070. (if com (move-marker com-point (point)))
  1071. (move-to-window-line (1- val))
  1072. (if com (execute-com 'vi-window-top val com))))
  1073. (defun vi-window-middle (arg) ""
  1074. (interactive "P")
  1075. (let ((val (p-val arg))
  1076. (com (getCom arg)))
  1077. (if com (move-marker com-point (point)))
  1078. (move-to-window-line (+ (/ (1- (window-height)) 2) (1- val)))
  1079. (if com (execute-com 'vi-window-middle val com))))
  1080. (defun vi-window-bottom (arg) ""
  1081. (interactive "P")
  1082. (let ((val (p-val arg))
  1083. (com (getCom arg)))
  1084. (if com (move-marker com-point (point)))
  1085. (move-to-window-line (- val))
  1086. (if com (execute-com 'vi-window-bottom val com))))
  1087. (defun vi-line-to-top (arg) ""
  1088. (interactive "p")
  1089. (recenter (1- arg)))
  1090. (defun vi-line-to-middle (arg) ""
  1091. (interactive "p")
  1092. (recenter (+ (1- arg) (/ (1- (window-height)) 2))))
  1093. (defun vi-line-to-bottom (arg) ""
  1094. (interactive "p")
  1095. (recenter (- (window-height) (1+ arg))))
  1096. ;; paren match
  1097. (defun vi-paren-match (arg)
  1098. "(ARG) Go to the matching parenthesis."
  1099. (interactive "P")
  1100. (let ((com (getcom arg)))
  1101. (cond ((looking-at "[\(\[{]")
  1102. (if com (move-marker com-point (point)))
  1103. (forward-sexp 1)
  1104. (if com
  1105. (execute-com 'vi-paren-match nil com)
  1106. (backward-char)))
  1107. ((looking-at "[])}]")
  1108. (forward-char)
  1109. (if com (move-marker com-point (point)))
  1110. (backward-sexp 1)
  1111. (if com (execute-com 'vi-paren-match nil com)))
  1112. (t (error "")))))
  1113. ;; sentence and paragraph
  1114. (defun vi-forward-sentence (arg)
  1115. (interactive "P")
  1116. (let ((val (p-val arg))
  1117. (com (getcom arg)))
  1118. (if com (move-marker com-point (point)))
  1119. (forward-sentence val)
  1120. (if com (execute-com 'vi-forward-sentence nil com))))
  1121. (defun vi-backward-sentence (arg)
  1122. (interactive "P")
  1123. (let ((val (p-val arg))
  1124. (com (getcom arg)))
  1125. (if com (move-marker com-point (point)))
  1126. (backward-sentence val)
  1127. (if com (execute-com 'vi-backward-sentence nil com))))
  1128. (defun vi-forward-paragraph (arg)
  1129. (interactive "P")
  1130. (let ((val (p-val arg))
  1131. (com (getCom arg)))
  1132. (if com (move-marker com-point (point)))
  1133. (forward-paragraph val)
  1134. (if com (execute-com 'vi-forward-paragraph nil com))))
  1135. (defun vi-backward-paragraph (arg)
  1136. (interactive "P")
  1137. (let ((val (p-val arg))
  1138. (com (getCom arg)))
  1139. (if com (move-marker com-point (point)))
  1140. (backward-paragraph val)
  1141. (if com (execute-com 'vi-backward-paragraph nil com))))
  1142. ;; scrolling
  1143. (defun vi-scroll (arg) ""
  1144. (interactive "p")
  1145. (if (> arg 0)
  1146. (while (> arg 0)
  1147. (scroll-up)
  1148. (setq arg (1- arg)))
  1149. (while (> 0 arg)
  1150. (scroll-down)
  1151. (setq arg (1+ arg)))))
  1152. (defun vi-scroll-back (arg) ""
  1153. (interactive "p")
  1154. (vi-scroll (- arg)))
  1155. (defun vi-scroll-down (arg) ""
  1156. (interactive "P")
  1157. (if (null arg) (scroll-down (/ (window-height) 2))
  1158. (scroll-down arg)))
  1159. (defun vi-scroll-down-one (arg) ""
  1160. (interactive "p")
  1161. (scroll-down arg))
  1162. (defun vi-scroll-up (arg) ""
  1163. (interactive "P")
  1164. (if (null arg) (scroll-up (/ (window-height) 2))
  1165. (scroll-up arg)))
  1166. (defun vi-scroll-up-one (arg) ""
  1167. (interactive "p")
  1168. (scroll-up arg))
  1169. ;; splitting window
  1170. (defun buffer-in-two-windows ()
  1171. (interactive)
  1172. (delete-other-windows)
  1173. (split-window-vertically nil))
  1174. ;; searching
  1175. (defun vi-search-forward (arg)
  1176. "(ARG) Search a string forward. ARG is used to find the ARG's occurence
  1177. of the string. Default is vanilla search. Search mode can be toggled by
  1178. giving null search string."
  1179. (interactive "P")
  1180. (let ((val (P-val arg)) (com (getcom arg)))
  1181. (setq s-forward t
  1182. s-string (vi-read-string (if re-search "RE-/" "/")))
  1183. (if (string= s-string "")
  1184. (progn
  1185. (setq re-search (not re-search))
  1186. (message (format "Search mode changed to %s search."
  1187. (if re-search "regular expression"
  1188. "vanilla"))))
  1189. (vi-search s-string t val)
  1190. (if com
  1191. (progn
  1192. (move-marker com-point (mark))
  1193. (execute-com 'vi-search-next val com))))))
  1194. (defun vi-search-backward (arg)
  1195. "(ARG) Search a string backward. ARG is used to find the ARG's occurence
  1196. of the string. Default is vanilla search. Search mode can be toggled by
  1197. giving null search string."
  1198. (interactive "P")
  1199. (let ((val (P-val arg)) (com (getcom arg)))
  1200. (setq s-forward nil
  1201. s-string (vi-read-string (if re-search "RE-?" "?")))
  1202. (if (string= s-string "")
  1203. (progn
  1204. (setq re-search (not re-search))
  1205. (message (format "Search mode changed to %s search."
  1206. (if re-search "regular expression"
  1207. "vanilla"))))
  1208. (vi-search s-string nil val)
  1209. (if com
  1210. (progn
  1211. (move-marker com-point (mark))
  1212. (execute-com 'vi-search-next val com))))))
  1213. (defun vi-search (string forward arg &optional no-offset init-point)
  1214. "(STRING FORWARD COUNT &optional NO-OFFSET) Search COUNT's occurrence of
  1215. STRING. Search will be forward if FORWARD, otherwise backward."
  1216. (let ((val (p-val arg)) (com (getcom arg))
  1217. (null-arg (null (P-val arg))) (offset (not no-offset))
  1218. (case-fold-search vi-case-fold-search)
  1219. (start-point (or init-point (point))))
  1220. (if forward
  1221. (condition-case conditions
  1222. (progn
  1223. (if (and offset (not (eobp))) (forward-char))
  1224. (if re-search
  1225. (progn
  1226. (re-search-forward string nil nil val)
  1227. (re-search-backward string))
  1228. (search-forward string nil nil val)
  1229. (search-backward string))
  1230. (push-mark start-point))
  1231. (search-failed
  1232. (if (and null-arg vi-search-wrap-around)
  1233. (progn
  1234. (goto-char (point-min))
  1235. (vi-search string forward (cons 1 com) t start-point))
  1236. (goto-char start-point)
  1237. (signal 'search-failed (cdr conditions)))))
  1238. (condition-case conditions
  1239. (progn
  1240. (if re-search
  1241. (re-search-backward string nil nil val)
  1242. (search-backward string nil nil val))
  1243. (push-mark start-point))
  1244. (search-failed
  1245. (if (and null-arg vi-search-wrap-around)
  1246. (progn
  1247. (goto-char (point-max))
  1248. (vi-search string forward (cons 1 com) t start-point))
  1249. (goto-char start-point)
  1250. (signal 'search-failed (cdr conditions))))))))
  1251. (defun vi-search-next (arg)
  1252. (interactive "P")
  1253. (let ((val (p-val arg)) (com (getcom arg)))
  1254. (if (null s-string) (error "No previous search string."))
  1255. (vi-search s-string s-forward arg)
  1256. (if com (execute-com 'vi-search-next val com))))
  1257. (defun vi-search-Next (arg)
  1258. (interactive "P")
  1259. (let ((val (p-val arg)) (com (getcom arg)))
  1260. (if (null s-string) (error "No previous search string."))
  1261. (vi-search s-string (not s-forward) arg)
  1262. (if com (execute-com 'vi-search-Next val com))))
  1263. ;; visiting and killing files, buffers
  1264. (defun vi-switch-to-buffer ()
  1265. (interactive)
  1266. (let (buffer)
  1267. (setq buffer
  1268. (read-buffer
  1269. (format "switch to buffer \(%s\): "
  1270. (buffer-name (other-buffer (current-buffer))))))
  1271. (switch-to-buffer buffer)
  1272. (change-mode-to-vi)))
  1273. (defun vi-switch-to-buffer-other-window ()
  1274. (interactive)
  1275. (let (buffer)
  1276. (setq buffer
  1277. (read-buffer
  1278. (format "Switch to buffer \(%s\): "
  1279. (buffer-name (other-buffer (current-buffer))))))
  1280. (switch-to-buffer-other-window buffer)
  1281. (change-mode-to-vi)))
  1282. (defun vi-kill-buffer ()
  1283. (interactive)
  1284. (let (buffer buffer-name)
  1285. (setq buffer-name
  1286. (read-buffer
  1287. (format "Kill buffer \(%s\): "
  1288. (buffer-name (current-buffer)))))
  1289. (setq buffer
  1290. (if (null buffer-name)
  1291. (current-buffer)
  1292. (get-buffer buffer-name)))
  1293. (if (null buffer) (error "Buffer %s nonexistent." buffer-name))
  1294. (if (buffer-modified-p buffer)
  1295. (error "I can't kill modified buffer.")
  1296. (kill-buffer buffer))))
  1297. (defun vi-find-file ()
  1298. (interactive)
  1299. (let (file)
  1300. (setq file (read-file-name "visit file: "))
  1301. (switch-to-buffer (find-file-noselect file))
  1302. (change-mode-to-vi)))
  1303. (defun vi-find-file-other-window ()
  1304. (interactive)
  1305. (let (file)
  1306. (setq file (read-file-name "Visit file: "))
  1307. (switch-to-buffer-other-window (find-file-noselect file))
  1308. (change-mode-to-vi)))
  1309. (defun vi-info-on-file ()
  1310. "Give information of the file associated to the current buffer."
  1311. (interactive)
  1312. (message "\"%s\" line %d of %d"
  1313. (if (buffer-file-name) (buffer-file-name) "")
  1314. (1+ (count-lines (point-min) (point)))
  1315. (1+ (count-lines (point-min) (point-max)))))
  1316. ;; yank and pop
  1317. (defun vi-yank (text)
  1318. "yank TEXT silently."
  1319. (save-excursion
  1320. (push-mark-silent (point))
  1321. (insert text)
  1322. (exchange-point-and-mark))
  1323. (skip-chars-forward " \t"))
  1324. (defun vi-put-back (arg)
  1325. (interactive "P")
  1326. (let ((val (p-val arg))
  1327. (text (if use-register
  1328. (if (and (<= ?1 use-register) (<= use-register ?9))
  1329. (nth (- use-register 49) kill-ring-yank-pointer)
  1330. (get-register use-register))
  1331. (car kill-ring-yank-pointer))))
  1332. (if (null text)
  1333. (if use-register
  1334. (let ((reg use-register))
  1335. (setq use-register nil)
  1336. (error "Nothing in register %c" reg))
  1337. (error "")))
  1338. (setq use-register nil)
  1339. (if (end-with-a-newline-p text)
  1340. (progn
  1341. (next-line 1)
  1342. (beginning-of-line))
  1343. (if (and (not (eolp)) (not (eobp))) (forward-char)))
  1344. (setq d-com (list 'vi-put-back val nil use-register))
  1345. (loop val (vi-yank text))))
  1346. (defun vi-Put-back (arg)
  1347. (interactive "P")
  1348. (let ((val (p-val arg))
  1349. (text (if use-register
  1350. (if (and (<= ?1 use-register) (<= use-register ?9))
  1351. (nth (- use-register 49) kill-ring-yank-pointer)
  1352. (get-register use-register))
  1353. (car kill-ring-yank-pointer))))
  1354. (if (null text)
  1355. (if use-register
  1356. (let ((reg use-register))
  1357. (setq use-register nil)
  1358. (error "Nothing in register %c" reg))
  1359. (error "")))
  1360. (setq use-register nil)
  1361. (if (end-with-a-newline-p text) (beginning-of-line))
  1362. (setq d-com (list 'vi-Put-back val nil use-register))
  1363. (loop val (vi-yank text))))
  1364. (defun vi-delete-char (arg)
  1365. (interactive "P")
  1366. (let ((val (p-val arg)))
  1367. (setq d-com (list 'vi-delete-char val nil))
  1368. (if use-register
  1369. (progn
  1370. (if (and (<= ?A use-register) (<= use-register ?Z))
  1371. (vi-append-to-register
  1372. (+ use-register 32) (point) (- (point) val) nil)
  1373. (copy-to-register use-register (point) (- (point) val) nil))
  1374. (setq use-register nil)))
  1375. (delete-char val t)))
  1376. (defun vi-delete-backward-char (arg)
  1377. (interactive "P")
  1378. (let ((val (p-val arg)))
  1379. (setq d-com (list 'vi-delete-backward-char val nil))
  1380. (if use-register
  1381. (progn
  1382. (if (and (<= ?A use-register) (<= use-register ?Z))
  1383. (vi-append-to-register
  1384. (+ use-register 32) (point) (+ (point) val) nil)
  1385. (copy-to-register use-register (point) (+ (point) val) nil))
  1386. (setq use-register nil)))
  1387. (delete-backward-char val t)))
  1388. ;; join lines.
  1389. (defun vi-join-lines (arg)
  1390. "(ARG) Join this line to next, if ARG is nil. Otherwise, join
  1391. ARG lines"
  1392. (interactive "*P")
  1393. (let ((val (P-val arg)))
  1394. (setq d-com (list 'vi-join-lines val nil))
  1395. (loop (if (null val) 1 (1- val))
  1396. (progn
  1397. (end-of-line)
  1398. (if (not (eobp))
  1399. (progn
  1400. (forward-line 1)
  1401. (delete-region (point) (1- (point)))
  1402. (fixup-whitespace)))))))
  1403. ;; making small changes
  1404. (defun vi-change (beg end)
  1405. (setq c-string
  1406. (vi-read-string (format "%s => " (buffer-substring beg end))))
  1407. (vi-change-subr beg end))
  1408. (defun vi-change-subr (beg end)
  1409. (if use-register
  1410. (progn
  1411. (copy-to-register use-register beg end nil)
  1412. (setq use-register nil)))
  1413. (kill-region beg end)
  1414. (setq this-command 'vi-change)
  1415. (insert-string c-string))
  1416. ;; query replace
  1417. (defun vi-query-replace ()
  1418. "() Query replace. If you supply null string as the string to be
  1419. replaced, the query replace mode will toggle between string replace
  1420. and regexp replace."
  1421. (interactive)
  1422. (let (str)
  1423. (setq str (vi-read-string
  1424. (if re-query-replace "Query replace regexp: "
  1425. "Query replace: ")))
  1426. (if (string= str "")
  1427. (progn
  1428. (setq re-query-replace (not re-query-replace))
  1429. (message "Query replace mode changed to %s."
  1430. (if re-query-replace "regexp replace" "string replace")))
  1431. (if re-query-replace
  1432. (query-replace-regexp
  1433. str
  1434. (vi-read-string (format "Query replace regexp \"%s\" with: " str)))
  1435. (query-replace
  1436. str
  1437. (vi-read-string (format "Query replace \"%s\" with: " str)))))))
  1438. ;; marking
  1439. (defun vi-mark-beginning-of-buffer ()
  1440. (interactive)
  1441. (set-mark (point))
  1442. (goto-char (point-min))
  1443. (exchange-point-and-mark)
  1444. (message "mark set at the beginning of buffer"))
  1445. (defun vi-mark-end-of-buffer ()
  1446. (interactive)
  1447. (set-mark (point))
  1448. (goto-char (point-max))
  1449. (exchange-point-and-mark)
  1450. (message "mark set at the end of buffer"))
  1451. (defun vi-mark-point (char)
  1452. (interactive "c")
  1453. (cond ((and (<= ?a char) (<= char ?z))
  1454. (point-to-register (- char (- ?a ?\C-a))))
  1455. ((= char ?<) (vi-mark-beginning-of-buffer))
  1456. ((= char ?>) (vi-mark-end-of-buffer))
  1457. ((= char ?.) (push-mark))
  1458. ((= char ?,) (set-mark-command 1))
  1459. ((= char ?D) (mark-defun))
  1460. (t (error ""))))
  1461. (defun vi-goto-mark (arg)
  1462. (interactive "P")
  1463. (let ((char (read-char)) (com (getcom arg)))
  1464. (vi-goto-mark-subr char com nil)))
  1465. (defun vi-goto-mark-and-skip-white (arg)
  1466. (interactive "P")
  1467. (let ((char (read-char)) (com (getCom arg)))
  1468. (vi-goto-mark-subr char com t)))
  1469. (defun vi-goto-mark-subr (char com skip-white)
  1470. (cond ((and (<= ?a char) (<= char ?z))
  1471. (let ((buff (current-buffer)))
  1472. (if com (move-marker com-point (point)))
  1473. (goto-char (register-to-point (- char (- ?a ?\C-a))))
  1474. (if skip-white (back-to-indentation))
  1475. (change-mode-to-vi)
  1476. (if com
  1477. (if (equal buff (current-buffer))
  1478. (execute-com (if skip-white
  1479. 'vi-goto-mark-and-skip-white
  1480. 'vi-goto-mark)
  1481. nil com)
  1482. (switch-to-buffer buff)
  1483. (goto-char com-point)
  1484. (change-mode-to-vi)
  1485. (error "")))))
  1486. ((and (not skip-white) (= char ?`))
  1487. (if com (move-marker com-point (point)))
  1488. (exchange-point-and-mark)
  1489. (if com (execute-com 'vi-goto-mark nil com)))
  1490. ((and skip-white (= char ?'))
  1491. (if com (move-marker com-point (point)))
  1492. (exchange-point-and-mark)
  1493. (back-to-indentation)
  1494. (if com (execute-com 'vi-goto-mark-and-skip-white nil com)))
  1495. (t (error ""))))
  1496. (defun vi-exchange-point-and-mark ()
  1497. (interactive)
  1498. (exchange-point-and-mark)
  1499. (back-to-indentation))
  1500. (defun vi-keyboard-quit ()
  1501. (interactive)
  1502. (setq use-register nil)
  1503. (keyboard-quit))
  1504. (defun ctl-c-equivalent (arg)
  1505. (interactive "P")
  1506. (ctl-key-equivalent "\C-c" arg))
  1507. (defun ctl-x-equivalent (arg)
  1508. (interactive "P")
  1509. (ctl-key-equivalent "\C-x" arg))
  1510. (defun ctl-key-equivalent (key arg)
  1511. (let ((char (read-char)))
  1512. (if (and (<= ?A char) (<= char ?Z))
  1513. (setq char (- char (- ?A ?\C-a))))
  1514. (setq prefix-arg arg)
  1515. (command-execute
  1516. (get-editor-command emacs-local-map global-map
  1517. (format "%s%s" key (char-to-string char))))))
  1518. ;; commands in insertion mode
  1519. (defun delete-backward-word (arg)
  1520. (interactive "p")
  1521. (save-excursion
  1522. (set-mark (point))
  1523. (backward-word arg)
  1524. (delete-region (point) (mark))))
  1525. ;; key bindings
  1526. (set 'vi-command-mode-map (make-keymap))
  1527. (define-key vi-command-mode-map "\C-a" 'beginning-of-line)
  1528. (define-key vi-command-mode-map "\C-b" 'vi-scroll-back)
  1529. (define-key vi-command-mode-map "\C-c" 'vi-ctl-c)
  1530. (define-key vi-command-mode-map "\C-d" 'vi-scroll-up)
  1531. (define-key vi-command-mode-map "\C-e" 'vi-scroll-up-one)
  1532. (define-key vi-command-mode-map "\C-f" 'vi-scroll)
  1533. (define-key vi-command-mode-map "\C-g" 'vi-keyboard-quit)
  1534. (define-key vi-command-mode-map "\C-h" 'help-command)
  1535. (define-key vi-command-mode-map "\C-m" 'vi-scroll-back)
  1536. (define-key vi-command-mode-map "\C-n" 'vi-other-window)
  1537. (define-key vi-command-mode-map "\C-o" 'vi-ctl-open-line)
  1538. (define-key vi-command-mode-map "\C-u" 'vi-scroll-down)
  1539. (define-key vi-command-mode-map "\C-x" 'vi-ctl-x)
  1540. (define-key vi-command-mode-map "\C-y" 'vi-scroll-down-one)
  1541. (define-key vi-command-mode-map "\C-z" 'change-mode-to-emacs)
  1542. (define-key vi-command-mode-map "\e" 'vi-ESC)
  1543. (define-key vi-command-mode-map " " 'vi-scroll)
  1544. (define-key vi-command-mode-map "!" 'vi-command-argument)
  1545. (define-key vi-command-mode-map "\"" 'vi-command-argument)
  1546. (define-key vi-command-mode-map "#" 'vi-command-argument)
  1547. (define-key vi-command-mode-map "$" 'vi-goto-eol)
  1548. (define-key vi-command-mode-map "%" 'vi-paren-match)
  1549. (define-key vi-command-mode-map "&" 'vi-nil)
  1550. (define-key vi-command-mode-map "'" 'vi-goto-mark-and-skip-white)
  1551. (define-key vi-command-mode-map "(" 'vi-backward-sentence)
  1552. (define-key vi-command-mode-map ")" 'vi-forward-sentence)
  1553. (define-key vi-command-mode-map "*" 'call-last-kbd-macro)
  1554. (define-key vi-command-mode-map "+" 'vi-next-line-at-bol)
  1555. (define-key vi-command-mode-map "," 'vi-comma)
  1556. (define-key vi-command-mode-map "-" 'vi-previous-line-at-bol)
  1557. (define-key vi-command-mode-map "." 'vi-repeat)
  1558. (define-key vi-command-mode-map "/" 'vi-search-forward)
  1559. (define-key vi-command-mode-map "0" 'vi-beginning-of-line)
  1560. (define-key vi-command-mode-map "1" 'vi-digit-argument)
  1561. (define-key vi-command-mode-map "2" 'vi-digit-argument)
  1562. (define-key vi-command-mode-map "3" 'vi-digit-argument)
  1563. (define-key vi-command-mode-map "4" 'vi-digit-argument)
  1564. (define-key vi-command-mode-map "5" 'vi-digit-argument)
  1565. (define-key vi-command-mode-map "6" 'vi-digit-argument)
  1566. (define-key vi-command-mode-map "7" 'vi-digit-argument)
  1567. (define-key vi-command-mode-map "8" 'vi-digit-argument)
  1568. (define-key vi-command-mode-map "9" 'vi-digit-argument)
  1569. (define-key vi-command-mode-map ":" 'vi-ex)
  1570. (define-key vi-command-mode-map ";" 'vi-semi-colon)
  1571. (define-key vi-command-mode-map "<" 'vi-command-argument)
  1572. (define-key vi-command-mode-map "=" 'vi-command-argument)
  1573. (define-key vi-command-mode-map ">" 'vi-command-argument)
  1574. (define-key vi-command-mode-map "?" 'vi-search-backward)
  1575. (define-key vi-command-mode-map "j" 'vi-nil)
  1576. (define-key vi-command-mode-map "A" 'vi-Append)
  1577. (define-key vi-command-mode-map "B" 'vi-backward-Word)
  1578. (define-key vi-command-mode-map "C" 'ctl-c-equivalent)
  1579. (define-key vi-command-mode-map "D" 'vi-kill-line)
  1580. (define-key vi-command-mode-map "E" 'vi-end-of-Word)
  1581. (define-key vi-command-mode-map "F" 'vi-find-char-backward)
  1582. (define-key vi-command-mode-map "G" 'vi-goto-line)
  1583. (define-key vi-command-mode-map "H" 'vi-window-top)
  1584. (define-key vi-command-mode-map "I" 'vi-Insert)
  1585. (define-key vi-command-mode-map "J" 'vi-join-lines)
  1586. (define-key vi-command-mode-map "K" 'vi-kill-buffer)
  1587. (define-key vi-command-mode-map "L" 'vi-window-bottom)
  1588. (define-key vi-command-mode-map "M" 'vi-window-middle)
  1589. (define-key vi-command-mode-map "N" 'vi-search-Next)
  1590. (define-key vi-command-mode-map "O" 'vi-Open-line)
  1591. (define-key vi-command-mode-map "P" 'vi-Put-back)
  1592. (define-key vi-command-mode-map "Q" 'vi-query-replace)
  1593. (define-key vi-command-mode-map "R" 'vi-replace-string)
  1594. (define-key vi-command-mode-map "S" 'vi-switch-to-buffer-other-window)
  1595. (define-key vi-command-mode-map "T" 'vi-goto-char-backward)
  1596. (define-key vi-command-mode-map "U" 'vi-nil)
  1597. (define-key vi-command-mode-map "V" 'vi-find-file-other-window)
  1598. (define-key vi-command-mode-map "W" 'vi-forward-Word)
  1599. (define-key vi-command-mode-map "X" 'ctl-x-equivalent)
  1600. (define-key vi-command-mode-map "Y" 'vi-yank-line)
  1601. (define-key vi-command-mode-map "ZZ" 'save-buffers-kill-emacs)
  1602. (define-key vi-command-mode-map "[" 'vi-nil)
  1603. (define-key vi-command-mode-map "\\" 'escape-to-emacs)
  1604. (define-key vi-command-mode-map "]" 'vi-nil)
  1605. (define-key vi-command-mode-map "^" 'vi-bol-and-skip-white)
  1606. (define-key vi-command-mode-map "_" 'vi-nil)
  1607. (define-key vi-command-mode-map "`" 'vi-goto-mark)
  1608. (define-key vi-command-mode-map "a" 'vi-append)
  1609. (define-key vi-command-mode-map "b" 'vi-backward-word)
  1610. (define-key vi-command-mode-map "c" 'vi-command-argument)
  1611. (define-key vi-command-mode-map "d" 'vi-command-argument)
  1612. (define-key vi-command-mode-map "e" 'vi-end-of-word)
  1613. (define-key vi-command-mode-map "f" 'vi-find-char-forward)
  1614. (define-key vi-command-mode-map "g" 'vi-info-on-file)
  1615. (define-key vi-command-mode-map "h" 'vi-backward-char)
  1616. (define-key vi-command-mode-map "i" 'vi-insert)
  1617. (define-key vi-command-mode-map "j" 'vi-next-line)
  1618. (define-key vi-command-mode-map "k" 'vi-previous-line)
  1619. (define-key vi-command-mode-map "l" 'vi-forward-char)
  1620. (define-key vi-command-mode-map "m" 'vi-mark-point)
  1621. (define-key vi-command-mode-map "n" 'vi-search-next)
  1622. (define-key vi-command-mode-map "o" 'vi-open-line)
  1623. (define-key vi-command-mode-map "p" 'vi-put-back)
  1624. (define-key vi-command-mode-map "q" 'vi-nil)
  1625. (define-key vi-command-mode-map "r" 'vi-replace-char)
  1626. (define-key vi-command-mode-map "s" 'vi-switch-to-buffer)
  1627. (define-key vi-command-mode-map "t" 'vi-goto-char-forward)
  1628. (define-key vi-command-mode-map "u" 'vi-undo)
  1629. (define-key vi-command-mode-map "v" 'vi-find-file)
  1630. (define-key vi-command-mode-map "w" 'vi-forward-word)
  1631. (define-key vi-command-mode-map "x" 'vi-delete-char)
  1632. (define-key vi-command-mode-map "y" 'vi-command-argument)
  1633. (define-key vi-command-mode-map "zH" 'vi-line-to-top)
  1634. (define-key vi-command-mode-map "zM" 'vi-line-to-middle)
  1635. (define-key vi-command-mode-map "zL" 'vi-line-to-bottom)
  1636. (define-key vi-command-mode-map "z\C-m" 'vi-line-to-top)
  1637. (define-key vi-command-mode-map "z." 'vi-line-to-middle)
  1638. (define-key vi-command-mode-map "z-" 'vi-line-to-bottom)
  1639. (define-key vi-command-mode-map "{" 'vi-backward-paragraph)
  1640. (define-key vi-command-mode-map "|" 'vi-goto-col)
  1641. (define-key vi-command-mode-map "}" 'vi-forward-paragraph)
  1642. (define-key vi-command-mode-map "~" 'vi-nil)
  1643. (define-key vi-command-mode-map "\177" 'vi-delete-backward-char)
  1644. (define-key ctl-x-map "3" 'buffer-in-two-windows)
  1645. (define-key ctl-x-map "\C-i" 'insert-file)
  1646. (defun vip-version ()
  1647. (interactive)
  1648. (message "VIP version 2.7 of Feb 10, 1987"))
  1649. ;; implement ex commands
  1650. (defvar ex-token-type nil
  1651. "type of token. if non-nil, gives type of address. if nil, it
  1652. is a command.")
  1653. (defvar ex-token nil
  1654. "value of token.")
  1655. (defvar ex-addresses nil
  1656. "list of ex addresses")
  1657. (defvar ex-flag nil
  1658. "flag for ex flag")
  1659. (defvar ex-buffer nil
  1660. "name of ex buffer")
  1661. (defvar ex-count nil
  1662. "value of ex count")
  1663. (defvar ex-g-flag nil
  1664. "flag for global command")
  1665. (defvar ex-g-variant nil
  1666. "if t global command is executed on lines not matching ex-g-pat")
  1667. (defvar ex-reg-exp nil
  1668. "save reg-exp used in substitute")
  1669. (defvar ex-repl nil
  1670. "replace pattern for substitute")
  1671. (defvar ex-g-pat nil
  1672. "pattern for global command")
  1673. (defvar ex-map (make-sparse-keymap)
  1674. "save commnads for mapped keys")
  1675. (defvar ex-tag nil
  1676. "save ex tag")
  1677. (defvar ex-file nil)
  1678. (defvar ex-variant nil)
  1679. (defvar ex-offset nil)
  1680. (defvar ex-append nil)
  1681. (defun vi-nil ()
  1682. (interactive)
  1683. (error ""))
  1684. (defun looking-back (str)
  1685. "(STR) returns t if looking back reg-exp STR before point."
  1686. (and (save-excursion (re-search-backward str nil t))
  1687. (= (point) (match-end 0))))
  1688. (defun check-sub (str)
  1689. "check if ex-token is an initial segment of STR"
  1690. (let ((length (length ex-token)))
  1691. (if (and (<= length (length str))
  1692. (string= ex-token (substring str 0 length)))
  1693. (setq ex-token str)
  1694. (setq ex-token-type "non-command"))))
  1695. (defun get-ex-com-subr ()
  1696. "get a complete ex command"
  1697. (set-mark (point))
  1698. (re-search-forward "[a-z][a-z]*")
  1699. (setq ex-token-type "command")
  1700. (setq ex-token (buffer-substring (point) (mark)))
  1701. (exchange-point-and-mark)
  1702. (cond ((looking-at "a")
  1703. (cond ((looking-at "ab") (check-sub "abbreviate"))
  1704. ((looking-at "ar") (check-sub "args"))
  1705. (t (check-sub "append"))))
  1706. ((looking-at "[bh]") (setq ex-token-type "non-command"))
  1707. ((looking-at "c")
  1708. (if (looking-at "co") (check-sub "copy")
  1709. (check-sub "change")))
  1710. ((looking-at "d") (check-sub "delete"))
  1711. ((looking-at "e")
  1712. (if (looking-at "ex") (check-sub "ex")
  1713. (check-sub "edit")))
  1714. ((looking-at "f") (check-sub "file"))
  1715. ((looking-at "g") (check-sub "global"))
  1716. ((looking-at "i") (check-sub "insert"))
  1717. ((looking-at "j") (check-sub "join"))
  1718. ((looking-at "l") (check-sub "list"))
  1719. ((looking-at "m")
  1720. (cond ((looking-at "map") (check-sub "map"))
  1721. ((looking-at "mar") (check-sub "mark"))
  1722. (t (check-sub "move"))))
  1723. ((looking-at "n")
  1724. (if (looking-at "nu") (check-sub "number")
  1725. (check-sub "next")))
  1726. ((looking-at "o") (check-sub "open"))
  1727. ((looking-at "p")
  1728. (cond ((looking-at "pre") (check-sub "preserve"))
  1729. ((looking-at "pu") (check-sub "put"))
  1730. (t (check-sub "print"))))
  1731. ((looking-at "q") (check-sub "quit"))
  1732. ((looking-at "r")
  1733. (cond ((looking-at "rec") (check-sub "recover"))
  1734. ((looking-at "rew") (check-sub "rewind"))
  1735. (t (check-sub "read"))))
  1736. ((looking-at "s")
  1737. (cond ((looking-at "se") (check-sub "set"))
  1738. ((looking-at "sh") (check-sub "shell"))
  1739. ((looking-at "so") (check-sub "source"))
  1740. ((looking-at "st") (check-sub "stop"))
  1741. (t (check-sub "substitute"))))
  1742. ((looking-at "t")
  1743. (if (looking-at "ta") (check-sub "tag")
  1744. (check-sub "t")))
  1745. ((looking-at "u")
  1746. (cond ((looking-at "una") (check-sub "unabbreviate"))
  1747. ((looking-at "unm") (check-sub "unmap"))
  1748. (t (check-sub "undo"))))
  1749. ((looking-at "v")
  1750. (cond ((looking-at "ve") (check-sub "version"))
  1751. ((looking-at "vi") (check-sub "visual"))
  1752. (t (check-sub "v"))))
  1753. ((looking-at "w")
  1754. (if (looking-at "wq") (check-sub "wq")
  1755. (check-sub "write")))
  1756. ((looking-at "x") (check-sub "xit"))
  1757. ((looking-at "y") (check-sub "yank"))
  1758. ((looking-at "z") (check-sub "z")))
  1759. (exchange-point-and-mark))
  1760. (defun get-ex-token ()
  1761. "get an ex-token which is either an address or a command.
  1762. a token has type \(command, address, end-mark\) and value."
  1763. (save-window-excursion
  1764. (switch-to-buffer " *ex-working-space*")
  1765. (skip-chars-forward " \t")
  1766. (cond ((looking-at "[k#]")
  1767. (setq ex-token-type "command")
  1768. (setq ex-token (char-to-string (following-char)))
  1769. (forward-char 1))
  1770. ((looking-at "[a-z]") (get-ex-com-subr))
  1771. ((looking-at "\\.")
  1772. (forward-char 1)
  1773. (setq ex-token-type "dot"))
  1774. ((looking-at "[0-9]")
  1775. (set-mark (point))
  1776. (re-search-forward "[0-9]*")
  1777. (setq ex-token-type
  1778. (cond ((string= ex-token-type "plus") "add-number")
  1779. ((string= ex-token-type "minus") "sub-number")
  1780. (t "abs-number")))
  1781. (setq ex-token (string-to-int (buffer-substring (point) (mark)))))
  1782. ((looking-at "\\$")
  1783. (forward-char 1)
  1784. (setq ex-token-type "end"))
  1785. ((looking-at "%")
  1786. (forward-char 1)
  1787. (setq ex-token-type "whole"))
  1788. ((looking-at "+")
  1789. (cond ((or (looking-at "+[-+]") (looking-at "+[\n|]"))
  1790. (forward-char 1)
  1791. (insert-string "1")
  1792. (backward-char 1)
  1793. (setq ex-token-type "plus"))
  1794. ((looking-at "+[0-9]")
  1795. (forward-char 1)
  1796. (setq ex-token-type "plus"))
  1797. (t
  1798. (error "Badly formed address"))))
  1799. ((looking-at "-")
  1800. (cond ((or (looking-at "-[-+]") (looking-at "-[\n|]"))
  1801. (forward-char 1)
  1802. (insert-string "1")
  1803. (backward-char 1)
  1804. (setq ex-token-type "minus"))
  1805. ((looking-at "-[0-9]")
  1806. (forward-char 1)
  1807. (setq ex-token-type "minus"))
  1808. (t
  1809. (error "Badly formed address"))))
  1810. ((looking-at "/")
  1811. (forward-char 1)
  1812. (set-mark (point))
  1813. (let ((cont t))
  1814. (while (and (not (eolp)) cont)
  1815. ;;(re-search-forward "[^/]*/")
  1816. (re-search-forward "[^/]*\\(/\\|\n\\)")
  1817. (if (not (looking-back "[^\\\\]\\(\\\\\\\\\\)*\\\\/"))
  1818. (setq cont nil))))
  1819. (backward-char 1)
  1820. (setq ex-token (buffer-substring (point) (mark)))
  1821. (if (looking-at "/") (forward-char 1))
  1822. (setq ex-token-type "search-forward"))
  1823. ((looking-at "\\?")
  1824. (forward-char 1)
  1825. (set-mark (point))
  1826. (let ((cont t))
  1827. (while (and (not (eolp)) cont)
  1828. ;;(re-search-forward "[^\\?]*\\?")
  1829. (re-search-forward "[^\\?]*\\(\\?\\|\n\\)")
  1830. (if (not (looking-back "[^\\\\]\\(\\\\\\\\\\)*\\\\\\?"))
  1831. (setq cont nil))
  1832. (backward-char 1)
  1833. (if (not (looking-at "\n")) (forward-char 1))))
  1834. (setq ex-token-type "search-backward")
  1835. (setq ex-token (buffer-substring (1- (point)) (mark))))
  1836. ((looking-at ",")
  1837. (forward-char 1)
  1838. (setq ex-token-type "comma"))
  1839. ((looking-at ";")
  1840. (forward-char 1)
  1841. (setq ex-token-type "semi-colon"))
  1842. ((looking-at "[!=><&~]")
  1843. (setq ex-token-type "command")
  1844. (setq ex-token (char-to-string (following-char)))
  1845. (forward-char 1))
  1846. ((looking-at "'")
  1847. (setq ex-token-type "goto-mark")
  1848. (forward-char 1)
  1849. (cond ((looking-at "'") (setq ex-token nil))
  1850. ((looking-at "[a-z]") (setq ex-token (following-char)))
  1851. (t (error "Marks are ' and a-z")))
  1852. (forward-char 1))
  1853. ((looking-at "\n")
  1854. (setq ex-token-type "end-mark")
  1855. (setq ex-token "goto"))
  1856. (t
  1857. (error "illegal token")))))
  1858. (defun vi-ex ()
  1859. "ex commands within vi."
  1860. (interactive)
  1861. (setq ex-g-flag nil
  1862. ex-g-variant nil)
  1863. (let ((com-str (vi-read-string ":")) (address nil) (cont t) (dot (point)))
  1864. (save-window-excursion
  1865. (switch-to-buffer " *ex-working-space*")
  1866. (delete-region (point-min) (point-max))
  1867. (insert com-str "\n")
  1868. (goto-char (point-min)))
  1869. (setq ex-token-type "")
  1870. (setq ex-addresses nil)
  1871. (while cont
  1872. (get-ex-token)
  1873. (cond ((or (string= ex-token-type "command")
  1874. (string= ex-token-type "end-mark"))
  1875. (if address (setq ex-addresses (cons address ex-addresses)))
  1876. (execute-ex-command)
  1877. (save-window-excursion
  1878. (switch-to-buffer " *ex-working-space*")
  1879. (skip-chars-forward " \t")
  1880. (cond ((looking-at "|")
  1881. (forward-char 1))
  1882. ((looking-at "\n")
  1883. (setq cont nil))
  1884. (t (error "Extra character at end of a command")))))
  1885. ((string= ex-token-type "non-command")
  1886. (error (format "%s: Not an editor command" ex-token)))
  1887. ((string= ex-token-type "whole")
  1888. (setq ex-addresses
  1889. (cons (point-max) (cons (point-min) ex-addresses))))
  1890. ((string= ex-token-type "comma")
  1891. (setq ex-addresses
  1892. (cons (if (null address) (point) address) ex-addresses)))
  1893. ((string= ex-token-type "semi-colon")
  1894. (if address (setq dot address))
  1895. (setq ex-addresses
  1896. (cons (if (null address) (point) address) ex-addresses)))
  1897. (t (let ((ans (get-ex-address-subr address dot)))
  1898. (if ans (setq address ans))))))))
  1899. (defun ex-search-address (forward)
  1900. "search pattern and set address"
  1901. (if (string= ex-token "")
  1902. (if (null s-string) (error "No previous search string")
  1903. (setq ex-token s-string))
  1904. (setq s-string ex-token))
  1905. (if forward
  1906. (progn
  1907. (next-line 1)
  1908. (re-search-forward ex-token))
  1909. (next-line -1)
  1910. (re-search-backward ex-token)))
  1911. (defun get-ex-pat ()
  1912. "get a regular expression and set ex-variant if found"
  1913. (save-window-excursion
  1914. (switch-to-buffer " *ex-working-space*")
  1915. (skip-chars-forward " \t")
  1916. (if (looking-at "!")
  1917. (progn
  1918. (setq ex-g-variant (not ex-g-variant)
  1919. ex-g-flag (not ex-g-flag))
  1920. (forward-char 1)
  1921. (skip-chars-forward " \t")))
  1922. (if (looking-at "/")
  1923. (progn
  1924. (forward-char 1)
  1925. (set-mark (point))
  1926. (let ((cont t))
  1927. (while (and (not (eolp)) cont)
  1928. (re-search-forward "[^/]*\\(/\\|\n\\)")
  1929. ;;(re-search-forward "[^/]*/")
  1930. (if (not (looking-back "[^\\\\]\\(\\\\\\\\\\)*\\\\/"))
  1931. (setq cont nil))))
  1932. (setq ex-token
  1933. (if (= (mark) (point)) ""
  1934. (buffer-substring (1- (point)) (mark))))
  1935. (backward-char 1))
  1936. (setq ex-token nil))))
  1937. (defun get-ex-command ()
  1938. "get an ex command"
  1939. (save-window-excursion
  1940. (switch-to-buffer " *ex-working-space*")
  1941. (if (looking-at "/") (forward-char 1))
  1942. (skip-chars-forward " \t")
  1943. (cond ((looking-at "[a-z]")
  1944. (get-ex-com-subr)
  1945. (if (string= ex-token-type "non-command")
  1946. (error "%s: not an editor command" ex-token)))
  1947. ((looking-at "[!=><&~]")
  1948. (setq ex-token (char-to-string (following-char)))
  1949. (forward-char 1))
  1950. (t (error "Could not find an ex command")))))
  1951. (defun get-ex-opt-gc ()
  1952. "get an ex option g or c"
  1953. (save-window-excursion
  1954. (switch-to-buffer " *ex-working-space*")
  1955. (if (looking-at "/") (forward-char 1))
  1956. (skip-chars-forward " \t")
  1957. (cond ((looking-at "g")
  1958. (setq ex-token "g")
  1959. (forward-char 1)
  1960. t)
  1961. ((looking-at "c")
  1962. (setq ex-token "c")
  1963. (forward-char 1)
  1964. t)
  1965. (t nil))))
  1966. (defun default-ex-addresses (&optional whole-flag)
  1967. "compute default addresses. whole-flag means whole buffer."
  1968. (cond ((null ex-addresses)
  1969. (setq ex-addresses
  1970. (if whole-flag
  1971. (cons (point-max) (cons (point-min) nil))
  1972. (cons (point) (cons (point) nil)))))
  1973. ((null (cdr ex-addresses))
  1974. (setq ex-addresses
  1975. (cons (car ex-addresses) ex-addresses)))))
  1976. (defun get-ex-address ()
  1977. "get an ex-address and set ex-flag if a flag is found"
  1978. (let ((address (point)) (cont t))
  1979. (setq ex-token "")
  1980. (setq ex-flag nil)
  1981. (while cont
  1982. (get-ex-token)
  1983. (cond ((string= ex-token-type "command")
  1984. (if (or (string= ex-token "print") (string= ex-token "list")
  1985. (string= ex-token "#"))
  1986. (progn
  1987. (setq ex-flag t)
  1988. (setq cont nil))
  1989. (error "address expected")))
  1990. ((string= ex-token-type "end-mark")
  1991. (setq cont nil))
  1992. ((string= ex-token-type "whole")
  1993. (error "a trailing address is expected"))
  1994. ((string= ex-token-type "comma")
  1995. (error "Extra characters after an address"))
  1996. (t (let ((ans (get-ex-address-subr address (point))))
  1997. (if ans (setq address ans))))))
  1998. address))
  1999. (defun get-ex-address-subr (old-address dot)
  2000. "returns an address as a point"
  2001. (let ((address nil))
  2002. (cond ((string= ex-token-type "dot")
  2003. (setq address dot))
  2004. ((string= ex-token-type "add-number")
  2005. (save-excursion
  2006. (goto-char old-address)
  2007. (next-line (if (= old-address 0) (1- ex-token) ex-token))
  2008. (setq address (point))))
  2009. ((string= ex-token-type "sub-number")
  2010. (save-excursion
  2011. (goto-char old-address)
  2012. (next-line (- ex-token))
  2013. (setq address (point))))
  2014. ((string= ex-token-type "abs-number")
  2015. (save-excursion
  2016. (goto-char (point-min))
  2017. (if (= ex-token 0) (setq address 0)
  2018. (next-line (1- ex-token))
  2019. (setq address (point)))))
  2020. ((string= ex-token-type "end")
  2021. (setq address (point-max)))
  2022. ((string= ex-token-type "plus") t);; do nothing
  2023. ((string= ex-token-type "minus") t);; do nothing
  2024. ((string= ex-token-type "search-forward")
  2025. (save-excursion
  2026. (ex-search-address t)
  2027. (setq address (point))))
  2028. ((string= ex-token-type "search-backward")
  2029. (save-excursion
  2030. (ex-search-address nil)
  2031. (setq address (point))))
  2032. ((string= ex-token-type "goto-mark")
  2033. (save-excursion
  2034. (if (null ex-token)
  2035. (exchange-point-and-mark)
  2036. (goto-char (register-to-point (- ex-token (- ?a ?\C-a)))))
  2037. (setq address (point)))))
  2038. address))
  2039. (defun get-ex-buffer ()
  2040. "get a buffer name and set ex-count and ex-flag if found"
  2041. (setq ex-buffer nil)
  2042. (setq ex-count nil)
  2043. (setq ex-flag nil)
  2044. (save-window-excursion
  2045. (switch-to-buffer " *ex-working-space*")
  2046. (skip-chars-forward " \t")
  2047. (if (looking-at "[a-zA-Z]")
  2048. (progn
  2049. (setq ex-buffer (following-char))
  2050. (forward-char 1)
  2051. (skip-chars-forward " \t")))
  2052. (if (looking-at "[0-9]")
  2053. (progn
  2054. (set-mark (point))
  2055. (re-search-forward "[0-9][0-9]*")
  2056. (setq ex-count (string-to-int (buffer-substring (point) (mark))))
  2057. (skip-chars-forward " \t")))
  2058. (if (looking-at "[pl#]")
  2059. (progn
  2060. (setq ex-flag t)
  2061. (forward-char 1)))
  2062. (if (not (looking-at "[\n|]"))
  2063. (error "Illegal extra characters"))))
  2064. (defun get-ex-count ()
  2065. (setq ex-variant nil
  2066. ex-count nil
  2067. ex-flag nil)
  2068. (save-window-excursion
  2069. (switch-to-buffer " *ex-working-space*")
  2070. (skip-chars-forward " \t")
  2071. (if (looking-at "!")
  2072. (progn
  2073. (setq ex-variant t)
  2074. (forward-char 1)))
  2075. (skip-chars-forward " \t")
  2076. (if (looking-at "[0-9]")
  2077. (progn
  2078. (set-mark (point))
  2079. (re-search-forward "[0-9][0-9]*")
  2080. (setq ex-count (string-to-int (buffer-substring (point) (mark))))
  2081. (skip-chars-forward " \t")))
  2082. (if (looking-at "[pl#]")
  2083. (progn
  2084. (setq ex-flag t)
  2085. (forward-char 1)))
  2086. (if (not (looking-at "[\n|]"))
  2087. (error "Illegal extra characters"))))
  2088. (defun get-ex-file ()
  2089. "get a file name and set ex-variant, ex-append and ex-offset if found"
  2090. (setq ex-file nil
  2091. ex-variant nil
  2092. ex-append nil
  2093. ex-offset nil)
  2094. (save-window-excursion
  2095. (switch-to-buffer " *ex-working-space*")
  2096. (skip-chars-forward " \t")
  2097. (if (looking-at "!")
  2098. (progn
  2099. (setq ex-variant t)
  2100. (forward-char 1)
  2101. (skip-chars-forward " \t")))
  2102. (if (looking-at ">>")
  2103. (progn
  2104. (setq ex-append t
  2105. ex-variant t)
  2106. (forward-char 2)
  2107. (skip-chars-forward " \t")))
  2108. (if (looking-at "+")
  2109. (progn
  2110. (forward-char 1)
  2111. (set-mark (point))
  2112. (re-search-forward "[ \t\n]")
  2113. (backward-char 1)
  2114. (setq ex-offset (buffer-substring (point) (mark)))
  2115. (forward-char 1)
  2116. (skip-chars-forward " \t")))
  2117. (set-mark (point))
  2118. (re-search-forward "[ \t\n]")
  2119. (backward-char 1)
  2120. (setq ex-file (buffer-substring (point) (mark)))))
  2121. (defun execute-ex-command ()
  2122. "execute ex command using the value of addresses."
  2123. (cond ((string= ex-token "goto") (ex-goto))
  2124. ((string= ex-token "copy") (ex-copy nil))
  2125. ((string= ex-token "delete") (ex-delete))
  2126. ((string= ex-token "edit") (ex-edit))
  2127. ((string= ex-token "file") (vi-info-on-file))
  2128. ((string= ex-token "global") (ex-global nil))
  2129. ((string= ex-token "join") (ex-line "join"))
  2130. ((string= ex-token "k") (ex-mark))
  2131. ((string= ex-token "mark") (ex-mark))
  2132. ((string= ex-token "map") (ex-map))
  2133. ((string= ex-token "move") (ex-copy t))
  2134. ((string= ex-token "put") (ex-put))
  2135. ((string= ex-token "quit") (ex-quit))
  2136. ((string= ex-token "read") (ex-read))
  2137. ((string= ex-token "set") (ex-set))
  2138. ((string= ex-token "shell") (ex-shell))
  2139. ((string= ex-token "substitute") (ex-substitute))
  2140. ((string= ex-token "stop") (suspend-emacs))
  2141. ((string= ex-token "t") (ex-copy nil))
  2142. ((string= ex-token "tag") (ex-tag))
  2143. ((string= ex-token "undo") (vi-undo))
  2144. ((string= ex-token "unmap") (ex-unmap))
  2145. ((string= ex-token "v") (ex-global t))
  2146. ((string= ex-token "version") (vip-version))
  2147. ((string= ex-token "visual") (ex-edit))
  2148. ((string= ex-token "write") (ex-write nil))
  2149. ((string= ex-token "wq") (ex-write t))
  2150. ((string= ex-token "yank") (ex-yank))
  2151. ((string= ex-token "!") (ex-command))
  2152. ((string= ex-token "=") (ex-line-no))
  2153. ((string= ex-token ">") (ex-line "right"))
  2154. ((string= ex-token "<") (ex-line "left"))
  2155. ((string= ex-token "&") (ex-substitute t))
  2156. ((string= ex-token "~") (ex-substitute t t))
  2157. ((or (string= ex-token "append")
  2158. (string= ex-token "args")
  2159. (string= ex-token "change")
  2160. (string= ex-token "insert")
  2161. (string= ex-token "open")
  2162. )
  2163. (error (format "%s: no such command from VIP" ex-token)))
  2164. ((or (string= ex-token "abbreviate")
  2165. (string= ex-token "list")
  2166. (string= ex-token "next")
  2167. (string= ex-token "print")
  2168. (string= ex-token "preserve")
  2169. (string= ex-token "recover")
  2170. (string= ex-token "rewind")
  2171. (string= ex-token "source")
  2172. (string= ex-token "unabbreviate")
  2173. (string= ex-token "xit")
  2174. (string= ex-token "z")
  2175. )
  2176. (error (format "%s: not implemented in VIP" ex-token)))
  2177. (t (error (format "%s: Not an editor command" ex-token)))))
  2178. (defun ex-goto ()
  2179. "ex goto command"
  2180. (if (null ex-addresses)
  2181. (setq ex-addresses (cons (dot) nil)))
  2182. (push-mark (point))
  2183. (goto-char (car ex-addresses))
  2184. (beginning-of-line))
  2185. (defun ex-copy (del-flag)
  2186. "ex copy and move command. del-flag means delete."
  2187. (default-ex-addresses)
  2188. (let ((address (get-ex-address))
  2189. (end (car ex-addresses)) (beg (car (cdr ex-addresses))))
  2190. (goto-char end)
  2191. (save-excursion
  2192. (set-mark beg)
  2193. (enlarge-region (mark) (point))
  2194. (if (or ex-g-flag ex-g-variant)
  2195. ;; global or it's variant
  2196. (progn
  2197. (if del-flag (kill-region (mark) (point))
  2198. (copy-region-as-kill (mark) (point)))
  2199. (save-window-excursion
  2200. (switch-to-buffer " *ex-working-space")
  2201. (delete-region (point-min) (point-max))
  2202. (insert-string (car kill-ring-yank-pointer))
  2203. (goto-char (point-min))
  2204. (while (not (eobp))
  2205. (end-of-line)
  2206. (set-mark (point))
  2207. (beginning-of-line)
  2208. (if (re-search-forward ex-g-pat (mark) t)
  2209. (if ex-g-flag
  2210. (next-line 1)
  2211. (beginning-of-line)
  2212. (delete-region (point) (1+ (mark))))
  2213. (if ex-g-variant
  2214. (next-line 1)
  2215. (beginning-of-line)
  2216. (delete-region (point) (1+ (mark))))))
  2217. (if del-flag (kill-region (point-min) (point-max))
  2218. (copy-region-as-kill (point-min) (point-max)))))
  2219. (if del-flag (kill-region (point) (mark))
  2220. (copy-region-as-kill (point) (mark))))
  2221. (if ex-flag
  2222. (progn
  2223. (with-output-to-temp-buffer "*copy text*"
  2224. (princ
  2225. (if (or del-flag ex-g-flag ex-g-variant)
  2226. (car kill-ring-yank-pointer)
  2227. (buffer-substring (point) (mark)))))
  2228. (condition-case nil
  2229. (progn
  2230. (vi-read-string "[Hit return to continue] ")
  2231. (save-excursion (kill-buffer "*copy text*")))
  2232. (quit
  2233. (save-excursion (kill-buffer "*copy text*"))
  2234. (signal 'quit nil))))))
  2235. (if (= address 0)
  2236. (goto-char (point-min))
  2237. (goto-char address)
  2238. (next-line 1)
  2239. (beginning-of-line))
  2240. (insert-string (car kill-ring-yank-pointer))))
  2241. (defun ex-delete ()
  2242. "ex delete"
  2243. (default-ex-addresses)
  2244. (get-ex-buffer)
  2245. (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))))
  2246. (if (> beg end) (error "First address exceeds second"))
  2247. (save-excursion
  2248. (enlarge-region beg end)
  2249. (let ((limit (point-marker)))
  2250. (exchange-point-and-mark)
  2251. (if (or ex-g-flag ex-g-variant)
  2252. (while (and (not (eobp)) (<= (point) limit))
  2253. (end-of-line)
  2254. (set-mark (point))
  2255. (beginning-of-line)
  2256. (let ((found (re-search-forward ex-g-pat (mark) t)))
  2257. (if (or (and ex-g-flag found)
  2258. (and ex-g-variant (not found)))
  2259. (if ex-count
  2260. (progn
  2261. (beginning-of-line)
  2262. (set-mark (point))
  2263. (next-line ex-count)
  2264. (delete-region (point) (mark)))
  2265. (beginning-of-line)
  2266. (delete-region (point) (1+ (mark))))
  2267. (goto-char (1+ (mark))))))))
  2268. (if ex-count
  2269. (progn
  2270. (set-mark (point))
  2271. (next-line (1- ex-count)))
  2272. (set-mark end))
  2273. (enlarge-region (point) (mark))
  2274. (if ex-flag
  2275. ;; show text to be deleted and ask for confirmation
  2276. (progn
  2277. (with-output-to-temp-buffer " *delete text*"
  2278. (princ (buffer-substring (point) (mark))))
  2279. (condition-case conditions
  2280. (vi-read-string "[Hit return to continue] ")
  2281. (quit
  2282. (save-excursion (kill-buffer " *delete text*"))
  2283. (error "")))
  2284. (save-excursion (kill-buffer " *delete text*")))
  2285. (if ex-buffer
  2286. (if (and (<= ?A ex-buffer) (<= ex-buffer ?Z))
  2287. (vi-append-to-register
  2288. (+ ex-buffer 32) (point) (mark) nil)
  2289. (copy-to-register ex-buffer (point) (mark) nil)))
  2290. (delete-region (point) (mark))))))
  2291. (defun ex-edit ()
  2292. "ex-edit"
  2293. (get-ex-file)
  2294. (if (and (not ex-variant) (buffer-modified-p) buffer-file-name)
  2295. (error "No write since last change \(:e! overrides\)"))
  2296. (change-mode-to-emacs)
  2297. (switch-to-buffer
  2298. (find-file-noselect (concat default-directory ex-file)))
  2299. (change-mode-to-vi)
  2300. (goto-char (point-min))
  2301. (if ex-offset
  2302. (progn
  2303. (save-window-excursion
  2304. (switch-to-buffer " *ex-working-space*")
  2305. (delete-region (point-min) (point-max))
  2306. (insert ex-offset "\n")
  2307. (goto-char (point-min)))
  2308. (goto-char (get-ex-address))
  2309. (beginning-of-line))))
  2310. (defun ex-global (variant)
  2311. "ex global command"
  2312. (if variant
  2313. (setq ex-g-flag nil
  2314. ex-g-variant t)
  2315. (setq ex-g-flag t
  2316. ex-g-variant nil))
  2317. (get-ex-pat)
  2318. (if (null ex-token)
  2319. (error "Missing regular expression for global command"))
  2320. (if (string= ex-token "")
  2321. (if (null s-string) (error "No previous search string")
  2322. (setq ex-g-pat s-string))
  2323. (setq ex-g-pat ex-token
  2324. s-string ex-token))
  2325. (get-ex-command)
  2326. (if (string= ex-token "global")
  2327. (error "Global within global not allowed"))
  2328. (if (null ex-addresses)
  2329. (setq ex-addresses (cons (point-max) (cons (point-min) nil))))
  2330. (execute-ex-command))
  2331. (defun ex-line (com)
  2332. "ex line commands. COM is join, shift-right or shift-left."
  2333. (default-ex-addresses)
  2334. (get-ex-count)
  2335. (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))) point)
  2336. (if (> beg end) (error "First address exceeds second"))
  2337. (save-excursion
  2338. (enlarge-region beg end)
  2339. (let ((limit (point-marker)))
  2340. (exchange-point-and-mark)
  2341. (if (or ex-g-flag ex-g-variant)
  2342. (while (and (not (eobp)) (<= (point) limit))
  2343. (end-of-line)
  2344. (set-mark (point))
  2345. (beginning-of-line)
  2346. (if (re-search-forward ex-g-pat (mark) t)
  2347. (if ex-g-flag
  2348. (if ex-count
  2349. (progn
  2350. (beginning-of-line)
  2351. (set-mark (point))
  2352. (next-line ex-count)
  2353. (ex-line-subr com (point) (mark)))
  2354. (beginning-of-line)
  2355. (ex-line-subr com (point) (1+ (mark))))
  2356. (goto-char (1+ (mark))))
  2357. (if ex-g-variant
  2358. (if ex-count
  2359. (progn
  2360. (beginning-of-line)
  2361. (set-mark (point))
  2362. (next-line ex-count)
  2363. (ex-line-subr com (point) (mark)))
  2364. (beginning-of-line)
  2365. (ex-line-subr com (point) (1+ (mark))))
  2366. (goto-char (1+ (mark))))))
  2367. (if ex-count
  2368. (progn
  2369. (set-mark (point))
  2370. (next-line ex-count)))
  2371. (if ex-flag
  2372. ;; show text to be joined and ask for confirmation
  2373. (progn
  2374. (with-output-to-temp-buffer " *text*"
  2375. (princ (buffer-substring (point) (mark))))
  2376. (condition-case conditions
  2377. (progn
  2378. (vi-read-string "[Hit return to continue] ")
  2379. (ex-line-subr com (point) (mark)))
  2380. (quit
  2381. (ding)))
  2382. (save-excursion (kill-buffer " *text*")))
  2383. (ex-line-subr com (point) (mark)))))
  2384. (setq point (point)))
  2385. (goto-char (1- point))
  2386. (beginning-of-line)))
  2387. (defun ex-line-subr (com beg end)
  2388. (cond ((string= com "join")
  2389. (goto-char (min beg end))
  2390. (while (and (not (eobp)) (< (point) (max beg end)))
  2391. (end-of-line)
  2392. (if (and (<= (point) (max beg end)) (not (eobp)))
  2393. (progn
  2394. (forward-line 1)
  2395. (delete-region (point) (1- (point)))
  2396. (if (not ex-variant) (fixup-whitespace))))))
  2397. ((or (string= com "right") (string= com "left"))
  2398. (indent-rigidly
  2399. (min beg end) (max beg end)
  2400. (if (string= com "right") shift-width (- shift-width)))
  2401. (goto-char (max beg end))
  2402. (end-of-line)
  2403. (forward-char 1))))
  2404. (defun ex-mark ()
  2405. "ex mark"
  2406. (let (char)
  2407. (if (null ex-addresses)
  2408. (setq ex-addresses
  2409. (cons (point) nil)))
  2410. (save-window-excursion
  2411. (switch-to-buffer " *ex-working-space*")
  2412. (skip-chars-forward " \t")
  2413. (if (looking-at "[a-z]")
  2414. (progn
  2415. (setq char (following-char))
  2416. (forward-char 1)
  2417. (skip-chars-forward " \t")
  2418. (if (not (looking-at "[\n|]"))
  2419. (error "Extra characters at end of \"k\" command")))
  2420. (if (looking-at "[\n|]")
  2421. (error "\"k\" requires a following letter")
  2422. (error "Mark must specify a letter"))))
  2423. (save-excursion
  2424. (goto-char (car ex-addresses))
  2425. (point-to-register (- char (- ?a ?\C-a))))))
  2426. (defun ex-map ()
  2427. "ex map"
  2428. (let (char string)
  2429. (save-window-excursion
  2430. (switch-to-buffer " *ex-working-space*")
  2431. (skip-chars-forward " \t")
  2432. (setq char (char-to-string (following-char)))
  2433. (forward-char 1)
  2434. (skip-chars-forward " \t")
  2435. (if (looking-at "[\n|]") (error "Missing rhs"))
  2436. (set-mark (point))
  2437. (end-of-buffer)
  2438. (backward-char 1)
  2439. (setq string (buffer-substring (mark) (point))))
  2440. (if (not (lookup-key ex-map char))
  2441. (define-key ex-map char
  2442. (or (lookup-key vi-command-mode-map char) 'vi-nil)))
  2443. (define-key vi-command-mode-map char
  2444. (eval
  2445. (list 'quote
  2446. (cons 'lambda
  2447. (list '(count)
  2448. '(interactive "p")
  2449. (list 'execute-kbd-macro string 'count))))))))
  2450. (defun ex-unmap ()
  2451. "ex unmap"
  2452. (let (char)
  2453. (save-window-excursion
  2454. (switch-to-buffer " *ex-working-space*")
  2455. (skip-chars-forward " \t")
  2456. (setq char (char-to-string (following-char)))
  2457. (forward-char 1)
  2458. (skip-chars-forward " \t")
  2459. (if (not (looking-at "[\n|]")) (error "Macro must be a character")))
  2460. (if (not (lookup-key ex-map char))
  2461. (error "That macro wasn't mapped"))
  2462. (define-key vi-command-mode-map char (lookup-key ex-map char))
  2463. (define-key ex-map char nil)))
  2464. (defun ex-put ()
  2465. "ex put"
  2466. (let ((point (if (null ex-addresses) (point) (car ex-addresses))))
  2467. (get-ex-buffer)
  2468. (setq use-register ex-buffer)
  2469. (goto-char point)
  2470. (if (= point 0) (vi-Put-back 1) (vi-put-back 1))))
  2471. (defun ex-quit ()
  2472. "ex quit"
  2473. (let (char)
  2474. (save-window-excursion
  2475. (switch-to-buffer " *ex-working-space*")
  2476. (skip-chars-forward " \t")
  2477. (setq char (following-char)))
  2478. (if (= char ?!) (kill-emacs t) (save-buffers-kill-emacs))))
  2479. (defun ex-read ()
  2480. "ex read"
  2481. (let ((point (if (null ex-addresses) (point) (car ex-addresses)))
  2482. (variant nil) command file)
  2483. (goto-char point)
  2484. (if (not (= point 0)) (next-line 1))
  2485. (beginning-of-line)
  2486. (save-window-excursion
  2487. (switch-to-buffer " *ex-working-space*")
  2488. (skip-chars-forward " \t")
  2489. (if (looking-at "!")
  2490. (progn
  2491. (setq variant t)
  2492. (forward-char 1)
  2493. (skip-chars-forward " \t")
  2494. (set-mark (point))
  2495. (end-of-line)
  2496. (setq command (buffer-substring (mark) (point))))
  2497. (set-mark (point))
  2498. (re-search-forward "[ \t\n]")
  2499. (backward-char 1)
  2500. (setq file (buffer-substring (point) (mark)))))
  2501. (if variant
  2502. (shell-command command t)
  2503. (insert-file file))))
  2504. (defun ex-set ()
  2505. (eval (list 'setq
  2506. (read-variable "Variable: ")
  2507. (eval (read-minibuffer "Value: ")))))
  2508. (defun ex-shell ()
  2509. "ex shell"
  2510. (change-mode-to-emacs)
  2511. (shell))
  2512. (defun ex-substitute (&optional repeat r-flag)
  2513. "ex substitute. if REPEAT use previous reg-exp which is ex-reg-exp or
  2514. s-string"
  2515. (let (pat repl (opt-g nil) (opt-c nil) (matched-pos nil))
  2516. (if repeat (setq ex-token nil) (get-ex-pat))
  2517. (if (null ex-token)
  2518. (setq pat (if r-flag s-string ex-reg-exp)
  2519. repl ex-repl)
  2520. (setq pat (if (string= ex-token "") s-string ex-token))
  2521. (setq s-string pat
  2522. ex-reg-exp pat)
  2523. (get-ex-pat)
  2524. (if (null ex-token)
  2525. (setq ex-token ""
  2526. ex-repl "")
  2527. (setq repl ex-token
  2528. ex-repl ex-token)))
  2529. (while (get-ex-opt-gc)
  2530. (if (string= ex-token "g") (setq opt-g t) (setq opt-c t)))
  2531. (get-ex-count)
  2532. (if ex-count
  2533. (save-excursion
  2534. (if ex-addresses (goto-char (car ex-addresses)))
  2535. (set-mark (point))
  2536. (next-line (1- ex-count))
  2537. (setq ex-addresses (cons (point) (cons (mark) nil))))
  2538. (if (null ex-addresses)
  2539. (setq ex-addresses (cons (point) (cons (point) nil)))
  2540. (if (null (cdr ex-addresses))
  2541. (setq ex-addresses (cons (car ex-addresses) ex-addresses)))))
  2542. (setq G opt-g)
  2543. (let ((beg (car ex-addresses)) (end (car (cdr ex-addresses)))
  2544. (cont t) eol-mark)
  2545. (save-excursion
  2546. (enlarge-region beg end)
  2547. (let ((limit (save-excursion
  2548. (goto-char (max (point) (mark)))
  2549. (point-marker))))
  2550. (goto-char (min (point) (mark)))
  2551. (if (or ex-g-flag ex-g-variant)
  2552. (while cont
  2553. (end-of-line)
  2554. (set-mark (point))
  2555. (beginning-of-line)
  2556. (let ((found (re-search-forward ex-g-pat (mark) t)))
  2557. (if (or (and ex-g-flag found)
  2558. (and ex-g-variant (not found)))
  2559. (progn
  2560. (end-of-line)
  2561. (setq eol-mark (dot-marker))
  2562. (beginning-of-line)
  2563. (if opt-g
  2564. (while (and (not (eolp))
  2565. (re-search-forward pat eol-mark t))
  2566. (if (or (not opt-c) (y-or-n-p "Replace? "))
  2567. (progn
  2568. (setq matched-pos (point))
  2569. (replace-match repl))))
  2570. (if (re-search-forward pat eol-mark t)
  2571. (if (or (not opt-c) (y-or-n-p "Replace? "))
  2572. (progn
  2573. (setq matched-pos (point))
  2574. (replace-match repl)))))
  2575. (end-of-line)
  2576. (if (= (point) limit) (setq cont nil) (forward-char)))
  2577. (end-of-line)
  2578. (if (= (point) limit) (setq cont nil) (forward-char)))))
  2579. (while (< (point) limit)
  2580. (end-of-line)
  2581. (setq eol-mark (dot-marker))
  2582. (beginning-of-line)
  2583. (if opt-g
  2584. (progn
  2585. (while (and (not (eolp))
  2586. (re-search-forward pat eol-mark t))
  2587. (if (or (not opt-c) (y-or-n-p "Replace? "))
  2588. (progn
  2589. (setq matched-pos (point))
  2590. (replace-match repl))))
  2591. (end-of-line)
  2592. (forward-char))
  2593. (if (and (re-search-forward pat eol-mark t)
  2594. (or (not opt-c) (y-or-n-p "Replace? ")))
  2595. (progn
  2596. (setq matched-pos (point))
  2597. (replace-match repl)))
  2598. (end-of-line)
  2599. (forward-char)))))))
  2600. (if matched-pos (goto-char matched-pos))
  2601. (beginning-of-line)
  2602. (if opt-c (message "done"))))
  2603. (defun ex-tag ()
  2604. "ex tag"
  2605. (let (tag)
  2606. (save-window-excursion
  2607. (switch-to-buffer " *ex-working-space*")
  2608. (skip-chars-forward " \t")
  2609. (set-mark (point))
  2610. (skip-chars-forward "^ |\t\n")
  2611. (setq tag (buffer-substring (mark) (point))))
  2612. (if (not (string= tag "")) (setq ex-tag tag))
  2613. (change-mode-to-emacs)
  2614. (condition-case conditions
  2615. (progn
  2616. (if (string= tag "")
  2617. (find-tag ex-tag t)
  2618. (find-tag-other-window ex-tag))
  2619. (change-mode-to-vi))
  2620. (error
  2621. (change-mode-to-vi)
  2622. (message-conditions conditions)))))
  2623. (defun ex-write (q-flag)
  2624. "ex write"
  2625. (default-ex-addresses t)
  2626. (get-ex-file)
  2627. (if (string= ex-file "")
  2628. (progn
  2629. (if (null buffer-file-name)
  2630. (error "No file associated with this buffer"))
  2631. (setq ex-file buffer-file-name))
  2632. (setq ex-file (expand-file-name ex-file)))
  2633. (if (and (not (string= ex-file (buffer-file-name)))
  2634. (file-exists-p ex-file)
  2635. (not ex-variant))
  2636. (error (format "\"%s\" File exists - use w! to override" ex-file)))
  2637. (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))))
  2638. (if (> beg end) (error "First address exceeds second"))
  2639. (save-excursion
  2640. (enlarge-region beg end)
  2641. (write-region (point) (mark) ex-file ex-append t)))
  2642. (if (null buffer-file-name) (setq buffer-file-name ex-file))
  2643. (if q-flag (save-buffers-kill-emacs)))
  2644. (defun ex-yank ()
  2645. "ex yank"
  2646. (default-ex-addresses)
  2647. (get-ex-buffer)
  2648. (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))))
  2649. (if (> beg end) (error "First address exceeds second"))
  2650. (save-excursion
  2651. (enlarge-region beg end)
  2652. (exchange-point-and-mark)
  2653. (if (or ex-g-flag ex-g-variant) (error "Can't yank within global"))
  2654. (if ex-count
  2655. (progn
  2656. (set-mark (point))
  2657. (next-line (1- ex-count)))
  2658. (set-mark end))
  2659. (enlarge-region (point) (mark))
  2660. (if ex-flag (error "Extra chacters at end of command"))
  2661. (if ex-buffer
  2662. (copy-to-register ex-buffer (point) (mark) nil))
  2663. (copy-region-as-kill (point) (mark)))))
  2664. (defun ex-command ()
  2665. "execute shell command"
  2666. (let (command)
  2667. (save-window-excursion
  2668. (switch-to-buffer " *ex-working-space*")
  2669. (skip-chars-forward " \t")
  2670. (set-mark (point))
  2671. (end-of-line)
  2672. (setq command (buffer-substring (mark) (point))))
  2673. (if (null ex-addresses)
  2674. (shell-command command)
  2675. (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))))
  2676. (if (null beg) (setq beg end))
  2677. (save-excursion
  2678. (goto-char beg)
  2679. (set-mark end)
  2680. (enlarge-region (point) (mark))
  2681. (shell-command-on-region (point) (mark) command t))
  2682. (goto-char beg)))))
  2683. (defun ex-line-no ()
  2684. "print line number"
  2685. (message "%d"
  2686. (1+ (count-lines
  2687. (point-min)
  2688. (if (null ex-addresses) (point-max) (car ex-addresses))))))
  2689. (if (file-exists-p "~/.vip") (load "~/.vip"))
  2690. ;; End of VIP