picolisp-wiki-mode.el (41038B)
1 ;;; picolisp-wiki-mode.el --- Emacs Major mode for PicoLisp-Wiki formatted text files 2 3 ;; Copyright (C) 2012-13 Thorsten Jolitz <tjolitz@gmail.com> 4 5 ;; Author: Thorsten Jolitz <tjolitz@gmail.com> 6 ;; Maintainer: Thorsten Jolitz <tjolitz@gmail.com> 7 ;; Created: September 01, 2012 8 ;; Version: 1.0 9 ;; Keywords: PicoLisp, wiki 10 ;; URL: http://picolisp.com/5000/!wiki?home 11 12 ;; This file is not part of GNU Emacs. 13 14 ;; This program is free software; you can redistribute it and/or modify 15 ;; it under the terms of the GNU General Public License as published by 16 ;; the Free Software Foundation; either version 2, or (at your option) 17 ;; any later version. 18 19 ;; This program is distributed in the hope that it will be useful, 20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 ;; GNU General Public License for more details. 23 24 ;; You should have received a copy of the GNU General Public License 25 ;; along with this program; if not, write to the Free Software 26 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, 27 ;; Boston, MA 02110-1301, USA. 28 29 ;;; Commentary: 30 31 ;; picolisp-wiki-mode is a major mode for editing text files for 32 ;; PicoLisp-Wiki in GNU Emacs. picolisp-wiki-mode is free software, 33 ;; licensed under the GNU GPL. 34 35 ;;; Dependencies: 36 37 ;; picolisp-wiki-mode requires easymenu, a standard package since GNU Emacs 38 ;; 19 and XEmacs 19, which provides a uniform interface for creating 39 ;; menus in GNU Emacs and XEmacs. 40 41 ;;; Installation: 42 43 ;; Make sure to place `picolisp-wiki-mode.el` somewhere in the 44 ;; load-path and add the following lines to your `.emacs` file to 45 ;; associate picolisp-wiki-mode with `.text` files: 46 47 (autoload 'picolisp-wiki-mode "picolisp-wiki-mode" 48 "Major mode for editing Picolisp-Wiki files" t) 49 (setq auto-mode-alist 50 ;; (cons '("\\.text" . picolisp-wiki-mode) auto-mode-alist)) 51 (cons '("\\.plw" . picolisp-wiki-mode) auto-mode-alist)) 52 53 ;; There is no consensus on an official file extension so change `.text` to 54 ;; `.plw`, `.lw`, `.lwik`, or whatever you call your picolisp-wiki files. 55 56 ;;; Customization: 57 58 ;; Although no configuration is *necessary* there are a few things 59 ;; that can be customized. The `M-x customize-mode` command 60 ;; provides an interface to all of the possible customizations. 61 62 ;; Usage: 63 64 ;; Keybindings for inserting are grouped by prefixes based on their 65 ;; function. For example, commands inserting links and lists begin 66 ;; with `C-c C-l`, those inserting floating content with `C-c C-f`, 67 ;; all other inserting commands with `C-c C-c`. The commands in each 68 ;; group are described below. You can obtain a list of all keybindings 69 ;; by pressing `C-c C-h`. 70 71 ;; ;; Element insertion 72 ;; "\C-c\C-l n" Insert Internal Link 73 ;; "\C-c\C-l x" Insert External Link 74 ;; "\C-c\C-l u" Insert Unordered List 75 ;; "\C-c\C-l o" Insert Ordered List 76 ;; "\C-c\C-l i" Insert List Item 77 ;; "\C-c\C-f l" Insert Left-Floating-Content 78 ;; "\C-c\C-f n" Insert Non-Floating Content 79 ;; "\C-c\C-f r" Insert Right-Floating-Content 80 ;; "\C-c\C-c k" Insert Line Breaks 81 ;; "\C-c\C-c 1" Insert Header 1 82 ;; "\C-c\C-c 2" Insert Header 2 83 ;; "\C-c\C-c 3" Insert Header 3 84 ;; "\C-c\C-c 4" Insert Header 4 85 ;; "\C-c\C-c 5" Insert Header 5 86 ;; "\C-c\C-c 6" Insert Header 6 87 ;; "\C-c\C-c b" Insert Bold 88 ;; "\C-c\C-c i" Insert Italic 89 ;; "\C-c\C-c u" Insert Underlined 90 ;; "\C-c\C-c p" Insert Pre Block 91 ;; "\C-c\C-c c" Insert Comment 92 ;; "\C-c\C-c -" Insert Horizontal Rule (hr) 93 ;; ;; Visibility cycling 94 ;; "<tab>" Picolisp Wiki Cycle 95 ;; "<S-iso-lefttab>" Picolisp Wiki Shifttab 96 ;; ;; Header navigation 97 ;; "C-M-n" Outline Next Visible Heading 98 ;; "C-M-p" Outline Previous Visible Heading 99 ;; "C-M-f" Outline Forward Same Level 100 ;; "C-M-b" Outline Backward Same Level 101 ;; "C-M-u" Outline Up Heading 102 103 ;; Many of the commands described above behave differently depending on 104 ;; whether Transient Mark mode is enabled or not. When it makes sense, 105 ;; if Transient Mark mode is on and a region is active, the command 106 ;; applies to the text in the region (e.g., `C-c C-c b` makes the region 107 ;; bold). For users who prefer to work outside of Transient Mark mode, 108 ;; in Emacs 22 it can be enabled temporarily by pressing `C-SPC C-SPC`. 109 ;; 110 ;; picolisp-wiki-mode supports outline-minor-mode as well as 111 ;; org-mode-style visibility cycling for PicoLisp-Wikli-style headers. 112 ;; There are two types of visibility cycling: Pressing `S-TAB` cycles 113 ;; globally between the table of contents view (headers only), outline 114 ;; view (top-level headers only), and the full document view. Pressing 115 ;; `TAB` while the point is at a header will cycle through levels of 116 ;; visibility for the subtree: completely folded, visible children, 117 ;; and fully visible. 118 119 ;; * Outline Navigation: 120 ;; 121 ;; Navigation between headings is possible using `outline-mode'. 122 ;; Use `C-M-n` and `C-M-p` to move between the next and previous 123 ;; visible headings. Similarly, `C-M-f` and `C-M-b` move to the 124 ;; next and previous visible headings at the same level as the one 125 ;; at the point. Finally, `C-M-u` will move up to a lower-level 126 ;; (more inclusive) visible heading. 127 ;; 128 ;; FIXME: different headers levels are not yet recognized by the outine 129 ;; commands. 130 131 132 ;;; Acknowledgments: 133 134 ;; picolisp-wiki-mode is based on markdown.el (available from ELPA). 135 ;; It has benefited greatly from the efforts of the following people: 136 ;; 137 ;; * Thorsten Jolitz <tjolitz [AT] gmail [DOT] com> 138 ;; * Doug Lewan <dougl [@] shubertticketing [DOT] com> 139 ;;; Bugs: 140 141 ;; picolisp-wiki-mode is developed and tested primarily using GNU 142 ;; Emacs 24, compatibility with earlier Emacsen is no priority. For 143 ;; bugs and todo's, see the HISTORY.org file in the github-repo 144 ;; (https://github.com/tj64/picolisp-wiki-mode). 145 ;; 146 ;; If you find any bugs in picolisp-wiki-mode, please construct a test case 147 ;; or a patch and email me at <tjolitz@gmail.com>. 148 149 ;;; History: 150 151 ;; picolisp-wiki-mode was written and is maintained by Thorsten 152 ;; Joltiz. The first version (0.9) was released on Sept 01, 2012. For 153 ;; further information see the HISTORY.org file in the github-repo 154 ;; (https://github.com/tj64/picolisp-wiki-mode). 155 156 157 ;;; Code: 158 159 (require 'easymenu) 160 (require 'outline) 161 (require 'cl) 162 163 ;;; Constants ================================================================= 164 165 (defconst picolisp-wiki-mode-version "1.0" 166 "Picolisp-Wiki mode version number.") 167 168 ;;; Customizable variables ==================================================== 169 170 (defvar picolisp-wiki-mode-hook nil 171 "Hook runs when Picolisp-Wiki mode is loaded.") 172 173 (defgroup picolisp-wiki nil 174 "Major mode for editing text files in Picolisp-Wiki format." 175 :prefix "picolisp-wiki-" 176 :group 'wp 177 :link '(url-link "http://picolisp.com/5000/!wiki?homef")) 178 179 180 (defcustom picolisp-wiki-hr-string "------------------------------------" 181 "String to use for horizonal rules." 182 :group 'picolisp-wiki 183 :type 'string) 184 185 (defcustom picolisp-wiki-uri-types 186 '("acap" "cid" "data" "dav" "fax" "file" "ftp" "gopher" "http" "https" 187 "imap" "ldap" "mailto" "mid" "modem" "news" "nfs" "nntp" "pop" "prospero" 188 "rtsp" "service" "sip" "tel" "telnet" "tip" "urn" "vemmi" "wais") 189 "Link types for syntax highlighting of URIs." 190 :group 'picolisp-wiki 191 :type 'list) 192 193 194 (defcustom picolisp-wiki-link-space-sub-char 195 "_" 196 "Character to use instead of spaces when mapping wiki links to filenames." 197 :group 'picolisp-wiki 198 :type 'string) 199 200 201 ;;; Font lock ================================================================= 202 203 (require 'font-lock) 204 205 (defvar picolisp-wiki-starting-brace-face 206 'picolisp-wiki-starting-brace-face 207 "Face name to use for starting braces.") 208 209 (defvar picolisp-wiki-closing-brace-face 210 'picolisp-wiki-closing-brace-face 211 "Face name to use for closing braces.") 212 213 (defvar picolisp-wiki-line-break-face 'picolisp-wiki-line-break-face 214 "Face name to use for line breaks.") 215 216 (defvar picolisp-wiki-italic-face 'picolisp-wiki-italic-face 217 "Face name to use for italic text.") 218 219 (defvar picolisp-wiki-bold-face 'picolisp-wiki-bold-face 220 "Face name to use for bold text.") 221 222 (defvar picolisp-wiki-underlined-face 'picolisp-wiki-underlined-face 223 "Face name to use for underlined text.") 224 225 (defvar picolisp-wiki-header-face 'picolisp-wiki-header-face 226 "Face name to use as a base for headers.") 227 228 (defvar picolisp-wiki-header-face-1 'picolisp-wiki-header-face-1 229 "Face name to use for level-1 headers.") 230 231 (defvar picolisp-wiki-header-face-2 'picolisp-wiki-header-face-2 232 "Face name to use for level-2 headers.") 233 234 (defvar picolisp-wiki-header-face-3 'picolisp-wiki-header-face-3 235 "Face name to use for level-3 headers.") 236 237 (defvar picolisp-wiki-header-face-4 'picolisp-wiki-header-face-4 238 "Face name to use for level-4 headers.") 239 240 (defvar picolisp-wiki-header-face-5 'picolisp-wiki-header-face-5 241 "Face name to use for level-5 headers.") 242 243 (defvar picolisp-wiki-header-face-6 'picolisp-wiki-header-face-6 244 "Face name to use for level-6 headers.") 245 246 (defvar picolisp-wiki-list-item-face 'picolisp-wiki-list-item-face 247 "Face name to use for list markers.") 248 249 (defvar picolisp-wiki-left-floating-content-face 250 'picolisp-wiki-left-floating-content-face 251 "Face name to use for left floating content.") 252 253 (defvar picolisp-wiki-non-floating-content-face 254 'picolisp-wiki-non-floating-content-face 255 "Face name to use for non floating content.") 256 257 (defvar picolisp-wiki-right-floating-content-face 258 'picolisp-wiki-right-floating-content-face 259 "Face name to use for right floating content.") 260 261 (defvar picolisp-wiki-pre-face 'picolisp-wiki-pre-face 262 "Face name to use for preformatted text.") 263 264 (defvar picolisp-wiki-link-label-face 'picolisp-wiki-link-label-face 265 "Face name to use for link labels.") 266 267 (defvar picolisp-wiki-url-face 'picolisp-wiki-url-face 268 "Face name to use for URLs.") 269 270 (defvar picolisp-wiki-link-title-face 'picolisp-wiki-link-title-face 271 "Face name to use for reference link titles.") 272 273 (defvar picolisp-wiki-comment-face 'picolisp-wiki-comment-face 274 "Face name to use for HTML comments.") 275 276 277 278 ;; FACE definitions 279 280 (defgroup picolisp-wiki-faces nil 281 "Faces used in Picolisp-Wiki Mode" 282 :group 'picolisp-wiki 283 :group 'faces) 284 285 (defface picolisp-wiki-hr-face 286 '((t (:inherit font-lock-comment-delimiter-face))) 287 "Face for starting braces." 288 :group 'picolisp-wiki-faces) 289 290 (defface picolisp-wiki-starting-brace-face 291 '((t (:inherit font-lock-comment-delimiter-face))) 292 "Face for starting braces." 293 :group 'picolisp-wiki-faces) 294 295 (defface picolisp-wiki-closing-brace-face 296 '((t (:inherit font-lock-comment-delimiter-face))) 297 "Face for closing braces." 298 :group 'picolisp-wiki-faces) 299 300 (defface picolisp-wiki-italic-face 301 '((t (:inherit font-lock-negation-char-face :slant italic))) 302 "Face for italic text." 303 :group 'picolisp-wiki-faces) 304 305 (defface picolisp-wiki-bold-face 306 '((t (:inherit font-lock-negation-char-face :weight bold))) 307 "Face for bold text." 308 :group 'picolisp-wiki-faces) 309 310 (defface picolisp-wiki-underlined-face 311 '((t (:inherit font-lock-negation-char-face :underline t))) 312 "Face for underlined text." 313 :group 'picolisp-wiki-faces) 314 315 (defface picolisp-wiki-line-break-face 316 '((t (:inherit font-lock-warning-face))) 317 "Face for underlined text." 318 :group 'picolisp-wiki-faces) 319 320 (defface picolisp-wiki-header-face 321 '((t (:inherit font-lock-function-name-face :weight bold))) 322 "Base face for headers." 323 :group 'picolisp-wiki-faces) 324 325 (defface picolisp-wiki-header-face-1 326 '((t (:inherit picolisp-wiki-header-face))) 327 "Face for level-1 headers." 328 :group 'picolisp-wiki-faces) 329 330 (defface picolisp-wiki-header-face-2 331 '((t (:inherit picolisp-wiki-header-face))) 332 "Face for level-2 headers." 333 :group 'picolisp-wiki-faces) 334 335 (defface picolisp-wiki-header-face-3 336 '((t (:inherit picolisp-wiki-header-face))) 337 "Face for level-3 headers." 338 :group 'picolisp-wiki-faces) 339 340 (defface picolisp-wiki-header-face-4 341 '((t (:inherit picolisp-wiki-header-face))) 342 "Face for level-4 headers." 343 :group 'picolisp-wiki-faces) 344 345 (defface picolisp-wiki-header-face-5 346 '((t (:inherit picolisp-wiki-header-face))) 347 "Face for level-5 headers." 348 :group 'picolisp-wiki-faces) 349 350 (defface picolisp-wiki-header-face-6 351 '((t (:inherit picolisp-wiki-header-face))) 352 "Face for level-6 headers." 353 :group 'picolisp-wiki-faces) 354 355 (defface picolisp-wiki-list-item-face 356 '((t (:inherit font-lock-string-face))) 357 "Face for list item markers." 358 :group 'picolisp-wiki-faces) 359 360 (defface picolisp-wiki-pre-face 361 '((t (:inherit font-lock-constant-face))) 362 ;; '((t (:inherit font-lock-string-face))) 363 "Face for preformatted text." 364 :group 'picolisp-wiki-faces) 365 366 (defface picolisp-wiki-internal-link-face 367 '((t (:inherit font-lock-keyword-face))) 368 "Face for internal links." 369 :group 'picolisp-wiki-faces) 370 371 (defface picolisp-wiki-external-link-face 372 '((t (:inherit font-lock-keyword-face))) 373 "Face for external links." 374 :group 'picolisp-wiki-faces) 375 376 (defface picolisp-wiki-url-face 377 '((t (:inherit font-lock-string-face))) 378 "Face for URLs." 379 :group 'picolisp-wiki-faces) 380 381 (defface picolisp-wiki-link-label-face 382 '((t (:inherit font-lock-keyword-face))) 383 "Face for reference link titles." 384 :group 'picolisp-wiki-faces) 385 386 (defface picolisp-wiki-comment-face 387 '((t (:inherit font-lock-comment-face))) 388 "Face for HTML comments." 389 :group 'picolisp-wiki-faces) 390 391 392 ;; REGEXP 393 ;; FIXME consider linebreaks in pattern 394 395 ;; [start] regexp by Doug Lewan (Newsgroups: gmane.emacs.help) 396 397 (defconst picolisp-wiki-regex-plain-text 398 (concat "\\([[:space:]]*[^}]+\\)[[:space:]]*" ; Matches "123$%^ Чебурашка &*(0-=" 399 ) 400 "Regular expression defining what 'plain text' is.") 401 402 (defconst picolisp-wiki-regex-bold-text 403 (concat "\\(!{\\)" 404 picolisp-wiki-regex-plain-text 405 "\\(}\\)") 406 "Regular expression defining what 'bold text' is.") 407 408 (defconst picolisp-wiki-regex-text 409 (concat "\\(" 410 picolisp-wiki-regex-plain-text 411 "\\|" 412 picolisp-wiki-regex-bold-text 413 "\\)") 414 "Regular expression defining what 'text'. 415 Text is a mix of plain text and bold text.") 416 417 (defconst picolisp-wiki-regex-list-item-text 418 (concat "\\(-{\\)" 419 picolisp-wiki-regex-text "+" 420 "\\(}\\)") 421 "Regular expression defining what a 'list item' is.") 422 423 ;; [end] regexp by Doug Lewan (Newsgroups: gmane.emacs.help) 424 425 ;; [start] testcode for regexp by Doug Lewan 426 427 ;; ;; 428 ;; ;; Sunny day test code 429 ;; ;; 430 ;; (defconst test-plain-text (list "foo" 431 ;; "foo bar " 432 ;; " foo bar baz bat" 433 ;; " --- 123$%^ Чебурашка &*(0-= --- ")) 434 ;; (defconst test-bold-text (mapcar (lambda (text) 435 ;; (concat "!{" text "}")) 436 ;; test-plain-text)) 437 ;; (defconst test-list-item-text (mapcar (lambda (list-text) 438 ;; (concat "-{" list-text "}")) 439 ;; (append test-plain-text test-bold-text))) 440 441 ;; (mapc (lambda (test-spec) 442 ;; (let ((re (car test-spec)) 443 ;; (test-data (cdr test-spec))) 444 ;; (mapc (lambda (item) 445 ;; (if (string-match re item) 446 ;; (message "PASS -- [[%s]] matches [[%s]]" re item) 447 ;; (message "FAIL -- [[%s]] DIDN'T match [[%s]]" re item)) 448 ;; (sit-for 1)) 449 ;; test-data))) 450 ;; (list (cons picolisp-wiki-regex-plain-text test-plain-text) 451 ;; (cons picolisp-wiki-regex-bold-text test-bold-text) 452 ;; (cons picolisp-wiki-regex-list-item-text test-list-item-text))) 453 454 ;; [end] testcode testcode for regexp by Doug Lewan 455 456 (defconst picolisp-wiki-regex-internal-link 457 "\\(={\\)\\([^ ]+\\)\\( \\)\\(.*\\)\\(}\\)" 458 "Regular expression for an internal link.") 459 460 (defconst picolisp-wiki-regex-external-link 461 "\\(\\^{\\)\\([^ ]+\\)\\( \\)\\(.*\\)\\(}\\)" 462 "Regular expression for an external link.") 463 464 (defconst picolisp-wiki-regex-comment 465 "\\(#{\\)\\([ 466 ]*[^}]+\\)\\(}\\)" 467 "Regular expression for an external link.") 468 469 (defconst picolisp-wiki-regex-header-1 470 "\\(1{\\)\\([ 471 ]*[^}]+\\)\\(}\\)" 472 "Regular expression for level 1 headers.") 473 474 (defconst picolisp-wiki-regex-header-2 475 "\\(2{\\)\\([ 476 ]*[^}]+\\)\\(}\\)" 477 "Regular expression for level 2 headers.") 478 479 (defconst picolisp-wiki-regex-header-3 480 "\\(3{\\)\\([ 481 ]*[^}]+\\)\\(}\\)" 482 "Regular expression for level 3 headers.") 483 484 (defconst picolisp-wiki-regex-header-4 485 "\\(4{\\)\\([ 486 ]*[^}]+\\)\\(}\\)" 487 "Regular expression for level 4 headers.") 488 489 (defconst picolisp-wiki-regex-header-5 490 "\\(5{\\)\\([ 491 ]*[^}]+\\)\\(}\\)" 492 "Regular expression for level 5 headers.") 493 494 (defconst picolisp-wiki-regex-header-6 495 "\\(6{\\)\\([ 496 ]*[^}]+\\)\\(}\\)" 497 "Regular expression for level 6 headers.") 498 499 (defconst picolisp-wiki-regex-hr 500 "\\(--\\)+\\(---\\)*$" 501 "Regular expression for matching Picolisp-Wiki horizontal rules.") 502 503 (defconst picolisp-wiki-regex-left-floating-content 504 "\\(<{\\)\\([ 505 ]*[^}]+\\)\\(}\\)" 506 "Regular expression for matching left-floating-content.") 507 508 (defconst picolisp-wiki-regex-non-floating-content 509 "\\(@{\\)\\([ 510 ]*[^}]+\\)\\(}\\)" 511 "Regular expression for matching non-floating-content.") 512 513 (defconst picolisp-wiki-regex-right-floating-content 514 "\\(>{\\)\\([ 515 ]*[^}]+\\)\\(}\\)" 516 "Regular expression for matching right-floating-content.") 517 518 (defconst picolisp-wiki-regex-pre-block 519 "\\(:{\\)\\([ 520 ]*[^}]+\\)\\(}\\)" 521 522 ;; "\\(:{\\)\\([ \t\n]*[^}]+\\)\\(}\\)" 523 524 ;; "\\(:{\\)\\([ 525 ;; ][^}]+\\)\\(}\\)" 526 "Regular expression for matching preformatted text sections.") 527 528 ;; (defconst picolisp-wiki-regex-unordered-list 529 ;; "\\(^[\\t ]*\\*{\\)\\([ ]*[ 530 ;; ]+\\)\\(-{.*}[ 531 ;; ]+\\)\\{1,\\}\\(}\\)" 532 ;; "Regular expression for matching unordered list markers.") 533 534 ;; (defconst picolisp-wiki-regex-ordered-list 535 ;; "\\(^[\\t ]*\\+{\\)\\([ ]*[ 536 ;; ]+\\)\\(-{.*}[ 537 ;; ]+\\)\\{1,\\}\\(}\\)" 538 ;; "Regular expression for matching ordered list markers.") 539 540 ;; (defconst picolisp-wiki-regex-unordered-list-start 541 ;; "\\(^\\*{\\)\\([ \t\n]*$\\)" 542 ;; "Regular expression for matching the start of an unordered list.") 543 544 ;; (defconst picolisp-wiki-regex-ordered-list-start 545 ;; "\\(^\\+{\\)\\([ \t\n]*$\\)" 546 ;; "Regular expression for matching the start of an ordered list.") 547 548 (defconst picolisp-wiki-regex-starting-brace 549 (concat "\\(\\*\\|\\+\\|-\\|&\\|/\\|_\\|\\^\\|" 550 "<\\|>\\|@\\|!\\|=\\|:\\|#\\|1\\|2\\|" 551 "3\\|4\\|5\\|6\\)\\({\\)") 552 "Regular expression for matching a starting brace.") 553 554 (defconst picolisp-wiki-regex-closing-brace 555 "\\([^\\]\\)\\(}\\)" 556 "Regular expression for matching a closing brace.") 557 558 (defconst picolisp-wiki-regex-list-item 559 "\\(-{\\)\\([ 560 ]*[^}]+\\)\\(}\\)" 561 "Regular expression for matching a list item.") 562 563 (defconst picolisp-wiki-regex-bold 564 "\\(!{\\)\\([ 565 ]*[^}]+\\)\\(}\\)" 566 "Regular expression for matching bold text.") 567 568 (defconst picolisp-wiki-regex-italic 569 "\\(/{\\)\\([ 570 ]*[^}]+\\)\\(}\\)" 571 "Regular expression for matching italic text.") 572 573 (defconst picolisp-wiki-regex-underlined 574 "\\(_{\\)\\([ 575 ]*[^}]+\\)\\(}\\)" 576 "Regular expression for matching underlined text.") 577 578 (defconst picolisp-wiki-regex-line-break 579 "\\(&{\\)\\([-]?[0-9]\\)\\(}\\)" 580 "Regular expression for matching line breaks.") 581 582 (defconst picolisp-wiki-regex-wiki-link 583 "\\[\\[\\([^]|]+\\)\\(|\\([^]]+\\)\\)?\\]\\]" 584 "Regular expression for matching wiki links. 585 This matches typical bracketed [[WikiLinks]] as well as 'aliased' 586 wiki links of the form [[PageName|link text]]. In this regular 587 expression, #1 matches the page name and #3 matches the link 588 text.") 589 590 (defconst picolisp-wiki-regex-uri 591 (concat 592 "\\(" (mapconcat 'identity picolisp-wiki-uri-types "\\|") 593 "\\):[^]\t\n\r<>,;() ]+") 594 "Regular expression for matching inline URIs.") 595 596 (defconst picolisp-wiki-regex-angle-uri 597 (concat 598 "\\(<\\)\\(" 599 (mapconcat 'identity picolisp-wiki-uri-types "\\|") 600 "\\):[^]\t\n\r<>,;()]+\\(>\\)") 601 "Regular expression for matching inline URIs in angle brackets.") 602 603 (defconst picolisp-wiki-regex-email 604 "<\\(\\sw\\|\\s_\\|\\s.\\)+@\\(\\sw\\|\\s_\\|\\s.\\)+>" 605 "Regular expression for matching inline email addresses.") 606 607 608 609 ;; Keywords 610 611 (defvar picolisp-wiki-mode-font-lock-keywords-basic 612 (list 613 (cons picolisp-wiki-regex-header-1 '(2 picolisp-wiki-header-face-1)) 614 (cons picolisp-wiki-regex-header-2 '(2 picolisp-wiki-header-face-2)) 615 (cons picolisp-wiki-regex-header-3 '(2 picolisp-wiki-header-face-3)) 616 (cons picolisp-wiki-regex-header-4 '(2 picolisp-wiki-header-face-4)) 617 (cons picolisp-wiki-regex-header-5 '(2 picolisp-wiki-header-face-5)) 618 (cons picolisp-wiki-regex-header-6 '(2 picolisp-wiki-header-face-6)) 619 (cons picolisp-wiki-regex-starting-brace 'picolisp-wiki-starting-brace-face) 620 (cons picolisp-wiki-regex-closing-brace '(2 picolisp-wiki-closing-brace-face)) 621 (cons picolisp-wiki-regex-pre-block '(2 picolisp-wiki-pre-face)) 622 (cons picolisp-wiki-regex-hr '(2 picolisp-wiki-hr-face)) 623 (cons picolisp-wiki-regex-line-break '(2 picolisp-wiki-line-break-face)) 624 (cons picolisp-wiki-regex-comment '(2 picolisp-wiki-comment-face)) 625 (cons picolisp-wiki-regex-angle-uri '(2 picolisp-wiki-url-face)) 626 (cons picolisp-wiki-regex-uri '(2 picolisp-wiki-url-face)) 627 (cons picolisp-wiki-regex-email '(2 picolisp-wiki-url-face)) 628 ;; (cons picolisp-wiki-regex-left-floating-content 629 ;; '(2 picolisp-wiki-left-floating-content-fact)) 630 ;; (cons picolisp-wiki-regex-non-floating-content 631 ;; '(2 picolisp-wiki-non-floating-content-fact)) 632 ;; (cons picolisp-wiki-regex-right-floating-content 633 ;; '(2 picolisp-wiki-right-floating-content-fact)) 634 (cons picolisp-wiki-regex-email '(2 picolisp-wiki-url-face)) 635 ;; changed from picolisp-wiki-regex-list-item 636 ;; (cons picolisp-wiki-regex-list-item '(2 picolisp-wiki-list-item-face)) 637 ;; (cons picolisp-wiki-regex-list-item-text 'picolisp-wiki-list-item-face) 638 (cons picolisp-wiki-regex-internal-link 639 '((2 picolisp-wiki-url-face t) 640 (4 picolisp-wiki-internal-link-face t))) 641 (cons picolisp-wiki-regex-external-link 642 '((2 picolisp-wiki-url-face t) 643 (4 picolisp-wiki-external-link-face t))) 644 (cons picolisp-wiki-regex-bold '(2 picolisp-wiki-bold-face)) 645 ;; (cons picolisp-wiki-regex-bold-text 'picolisp-wiki-bold-face) 646 (cons picolisp-wiki-regex-italic '(2 picolisp-wiki-italic-face)) 647 (cons picolisp-wiki-regex-underlined '(2 picolisp-wiki-underlined-face)) 648 ) 649 "Syntax highlighting for Picolisp-Wiki files.") 650 651 (defvar picolisp-wiki-mode-font-lock-keywords 652 (append picolisp-wiki-mode-font-lock-keywords-basic) 653 "Default highlighting expressions for Picolisp-Wiki mode.") 654 655 656 657 ;;; Syntax Table ============================================================== 658 659 (defvar picolisp-wiki-mode-syntax-table 660 (let ((picolisp-wiki-mode-syntax-table (make-syntax-table))) 661 (modify-syntax-entry ?\" "w" picolisp-wiki-mode-syntax-table) 662 picolisp-wiki-mode-syntax-table) 663 "Syntax table for `picolisp-wiki-mode'.") 664 665 666 667 ;;; Element Insertion ========================================================= 668 669 (defun picolisp-wiki-wrap-or-insert (s1 s2 &optional beg-newline-p) 670 "Insert the strings S1 and S2. 671 If Transient Mark mode is on and a region is active, wrap the strings S1 672 and S2 around the region." 673 (if (and transient-mark-mode mark-active) 674 (let ((a (region-beginning)) (b (region-end))) 675 (goto-char a) 676 (insert s1) 677 (goto-char (+ b (length s1))) 678 (insert s2)) 679 (if (not beg-newline-p) 680 (insert s1 s2) 681 (end-of-line) 682 (newline 2) 683 (insert s1 s2)))) 684 685 (defun picolisp-wiki-insert-hr () 686 "Insert a horizonal rule using `picolisp-wiki-hr-string'." 687 (interactive) 688 ;; Leading blank line 689 (when (and (>= (point) (+ (point-min) 2)) 690 (not (looking-back "\n\n" 2))) 691 (insert "\n")) 692 ;; Insert custom HR string 693 (insert (concat picolisp-wiki-hr-string "\n")) 694 ;; Following blank line 695 (backward-char) 696 (unless (looking-at "\n\n") 697 (insert "\n"))) 698 699 (defun picolisp-wiki-insert-bold () 700 "Insert markup for a bold word or phrase. 701 If Transient Mark mode is on and a region is active, it is made bold." 702 (interactive) 703 (picolisp-wiki-wrap-or-insert "!{" "}") 704 (backward-char 1)) 705 706 (defun picolisp-wiki-insert-italic () 707 "Insert markup for an italic word or phrase. 708 If Transient Mark mode is on and a region is active, it is made italic." 709 (interactive) 710 (picolisp-wiki-wrap-or-insert "/{" "}") 711 (backward-char 1)) 712 713 (defun picolisp-wiki-insert-underlined () 714 "Insert markup for an underlined word or phrase. 715 If Transient Mark mode is on and a region is active, it is underlined." 716 (interactive) 717 (picolisp-wiki-wrap-or-insert "_{" "}") 718 (backward-char 1)) 719 720 721 (defun picolisp-wiki-insert-pre-block () 722 "Insert markup for a pre-formatted block. 723 If Transient Mark mode is on and a region is active, it is marked 724 as inline code." 725 (interactive) 726 (picolisp-wiki-wrap-or-insert ":{" "}") 727 (backward-char 1)) 728 729 (defun picolisp-wiki-insert-comment () 730 "Insert markup for an comment. 731 If Transient Mark mode is on and a region is active, it is marked 732 as inline code." 733 (interactive) 734 (picolisp-wiki-wrap-or-insert "#{" "}") 735 (backward-char 1)) 736 737 738 (defun picolisp-wiki-insert-internal-link () 739 "Insert an internal link. 740 If Transient Mark mode is on and a region is active, it is used 741 as the link text." 742 (interactive) 743 (picolisp-wiki-wrap-or-insert "={" "}") 744 (backward-char 1)) 745 746 (defun picolisp-wiki-insert-external-link () 747 "Insert an external link. 748 If Transient Mark mode is on and a region is active, it is used 749 as the link text." 750 (interactive) 751 (picolisp-wiki-wrap-or-insert "^{" "}") 752 (backward-char 1)) 753 754 755 (defun picolisp-wiki-insert-left-floating-content () 756 "Insert an inline image tag of the form <{content}. 757 If Transient Mark mode is on and a region is active, it is used 758 as the alt text of the image." 759 (interactive) 760 (picolisp-wiki-wrap-or-insert "<{" "}") 761 (backward-char 1)) 762 763 (defun picolisp-wiki-insert-non-floating-content () 764 "Insert an inline image tag of the form @{content}. 765 If Transient Mark mode is on and a region is active, it is used 766 as the alt text of the image." 767 (interactive) 768 (picolisp-wiki-wrap-or-insert "@{" "}") 769 (backward-char 1)) 770 771 (defun picolisp-wiki-insert-right-floating-content () 772 "Insert an inline image tag of the form >{content}. 773 If Transient Mark mode is on and a region is active, it is used 774 as the alt text of the image." 775 (interactive) 776 (picolisp-wiki-wrap-or-insert ">{" "}") 777 (backward-char 1)) 778 779 780 (defun picolisp-wiki-insert-line-breaks (n) 781 "Insert line-breaks. With no prefix argument, insert 1 782 line-break. With prefix N, insert N line-breaks. With prefix N, 783 insert N line-breaks. With negative prefix -N, insert N 784 line-breaks and clear float style." 785 (interactive "p") 786 (unless n ; Test to see if n is defined 787 (setq n 1)) ; Default to level 1 header 788 (insert 789 (format "&{%d}" n ))) 790 791 792 (defun picolisp-wiki-insert-unordered-list () 793 "Insert an unordered list. 794 If Transient Mark mode is on and a region is active, it is wrapped in an unordered list (the region should only contain list-items)." 795 (interactive) 796 (end-of-line) 797 (newline) 798 (insert "*{") 799 (newline) 800 (insert " -{}") 801 (newline) 802 (insert "}") 803 (newline) 804 (search-backward "-{" nil t 1) 805 (forward-char 2)) 806 807 808 (defun picolisp-wiki-insert-ordered-list () 809 "Insert an ordered list. 810 If Transient Mark mode is on and a region is active, it is 811 wrapped in an ordered list (the region should only contain 812 list-items)." 813 (interactive) 814 (end-of-line) 815 (newline) 816 (insert "+{") 817 (newline) 818 (insert " -{}") 819 (newline) 820 (insert "}") 821 (newline) 822 (search-backward "-{" nil t 1) 823 (forward-char 2)) 824 825 826 ;; FIXME consider escaped braces '\{'and '\}' inside list items 827 (defun picolisp-wiki--inside-list-item-p (&optional second-trial-p) 828 "Return t if inside list-item, nil otherwise. 829 This function takes care of the (common) case when there is one 830 nested markup inside the list item, e.g. a link or a bold text, 831 and point is inside the nested markup braces." 832 (save-excursion 833 (let ((pt (point))) 834 (search-backward "{" nil t 1) 835 (backward-char) 836 (if (not (looking-at "-{")) 837 (if (and 838 (not second-trial-p) 839 (looking-at 840 (concat "\\(\\*\\|\\+\\|&\\|/\\|_\\|\\^\\|" 841 "<\\|>\\|@\\|!\\|=\\|:\\|#\\)\\({\\)"))) 842 (picolisp-wiki--inside-list-item-p 'SECOND-TRIAL-P) 843 nil) 844 (and 845 (if second-trial-p 846 (search-forward-regexp "}[^}]*}" nil t 1) 847 (search-forward "}" nil t 1)) 848 (setq item-end (point)) 849 (> item-end pt)))))) 850 851 (defun picolisp-wiki-insert-list-item () 852 "Insert a list-item. 853 If Transient Mark mode is on and a region is active, it becomes the text of a list item." 854 (interactive) 855 (if (not (picolisp-wiki--inside-list-item-p)) 856 (progn 857 (picolisp-wiki-wrap-or-insert "-{" "}") 858 (backward-char 1)) 859 (end-of-line) 860 (newline) 861 (insert " -{}") 862 (backward-char 1) 863 )) 864 865 866 (defun picolisp-wiki-insert-header-1 () 867 "Insert a first level picolisp-wiki-style header. 868 If Transient Mark mode is on and a region is active, it is used 869 as the header text." 870 (interactive) 871 (picolisp-wiki-insert-header 1)) 872 873 (defun picolisp-wiki-insert-header-2 () 874 "Insert a second level picolisp-wiki-style header. 875 If Transient Mark mode is on and a region is active, it is used 876 as the header text." 877 (interactive) 878 (picolisp-wiki-insert-header 2)) 879 880 (defun picolisp-wiki-insert-header-3 () 881 "Insert a third level picolisp-wiki-style header. 882 If Transient Mark mode is on and a region is active, it is used 883 as the header text." 884 (interactive) 885 (picolisp-wiki-insert-header 3)) 886 887 (defun picolisp-wiki-insert-header-4 () 888 "Insert a fourth level picolisp-wiki-style header. 889 If Transient Mark mode is on and a region is active, it is used 890 as the header text." 891 (interactive) 892 (picolisp-wiki-insert-header 4)) 893 894 (defun picolisp-wiki-insert-header-5 () 895 "Insert a fifth level picolisp-wiki-style header. 896 If Transient Mark mode is on and a region is active, it is used 897 as the header text." 898 (interactive) 899 (picolisp-wiki-insert-header 5)) 900 901 (defun picolisp-wiki-insert-header-6 () 902 "Insert a sixth level picolisp-wiki-style header. 903 If Transient Mark mode is on and a region is active, it is used 904 as the header text." 905 (interactive) 906 (picolisp-wiki-insert-header 6)) 907 908 (defun picolisp-wiki-insert-header (n) 909 "Insert an picolisp-wiki-style header. 910 With no prefix argument, insert a level-1 header. With prefix N, 911 insert a level-N header. If Transient Mark mode is on and the 912 region is active, it is used as the header text." 913 (interactive "p") 914 (unless n ; Test to see if n is defined 915 (setq n 1)) ; Default to level 1 header 916 (picolisp-wiki-wrap-or-insert 917 (concat (number-to-string n) "{") "}" 'BEG-NEWLINE-P) 918 (backward-char 1)) 919 920 921 922 ;;; Keymap ==================================================================== 923 924 (defvar picolisp-wiki-mode-map 925 (let ((map (make-keymap))) 926 ;; Element insertion 927 (define-key map "\C-c\C-ln" 'picolisp-wiki-insert-internal-link) 928 (define-key map "\C-c\C-lx" 'picolisp-wiki-insert-external-link) 929 (define-key map "\C-c\C-lu" 'picolisp-wiki-insert-unordered-list) 930 (define-key map "\C-c\C-lo" 'picolisp-wiki-insert-ordered-list) 931 (define-key map "\C-c\C-li" 'picolisp-wiki-insert-list-item) 932 (define-key map "\C-c\C-fl" 'picolisp-wiki-insert-left-floating-content) 933 (define-key map "\C-c\C-fn" 'picolisp-wiki-insert-non-floating-content) 934 (define-key map "\C-c\C-fr" 'picolisp-wiki-insert-right-floating-content) 935 (define-key map "\C-c\C-ck" 'picolisp-wiki-insert-line-breaks) 936 (define-key map "\C-c\C-c1" 'picolisp-wiki-insert-header-1) 937 (define-key map "\C-c\C-c2" 'picolisp-wiki-insert-header-2) 938 (define-key map "\C-c\C-c3" 'picolisp-wiki-insert-header-3) 939 (define-key map "\C-c\C-c4" 'picolisp-wiki-insert-header-4) 940 (define-key map "\C-c\C-c5" 'picolisp-wiki-insert-header-5) 941 (define-key map "\C-c\C-c6" 'picolisp-wiki-insert-header-6) 942 (define-key map "\C-c\C-cb" 'picolisp-wiki-insert-bold) 943 (define-key map "\C-c\C-ci" 'picolisp-wiki-insert-italic) 944 (define-key map "\C-c\C-cu" 'picolisp-wiki-insert-underlined) 945 (define-key map "\C-c\C-cp" 'picolisp-wiki-insert-pre-block) 946 (define-key map "\C-c\C-cc" 'picolisp-wiki-insert-comment) 947 (define-key map "\C-c\C-c-" 'picolisp-wiki-insert-hr) 948 ;; Visibility cycling 949 (define-key map (kbd "<tab>") 'picolisp-wiki-cycle) 950 (define-key map (kbd "<S-iso-lefttab>") 'picolisp-wiki-shifttab) 951 ;; Header navigation 952 (define-key map (kbd "C-M-n") 'outline-next-visible-heading) 953 (define-key map (kbd "C-M-p") 'outline-previous-visible-heading) 954 (define-key map (kbd "C-M-f") 'outline-forward-same-level) 955 (define-key map (kbd "C-M-b") 'outline-backward-same-level) 956 (define-key map (kbd "C-M-u") 'outline-up-heading) 957 ;; Picolisp-Wiki functions 958 ;; (define-key map "\C-c\C-cm" 'picolisp-wiki) 959 ;; (define-key map "\C-c\C-cp" 'picolisp-wiki-preview) 960 ;; (define-key map "\C-c\C-ce" 'picolisp-wiki-export) 961 ;; (define-key map "\C-c\C-cv" 'picolisp-wiki-export-and-view) 962 map) 963 "Keymap for Picolisp-Wiki major mode.") 964 965 966 967 968 969 ;;; Menu ================================================================== 970 971 (easy-menu-define picolisp-wiki-mode-menu picolisp-wiki-mode-map 972 "Menu for Picolisp-Wiki mode" 973 '("Picolisp-Wiki" 974 ("Show/Hide" 975 ["Cycle visibility" picolisp-wiki-cycle (outline-on-heading-p)] 976 ["Cycle global visibility" picolisp-wiki-shifttab]) 977 "---" 978 ("Headers" 979 ["First level" picolisp-wiki-insert-header-1] 980 ["Second level" picolisp-wiki-insert-header-2] 981 ["Third level" picolisp-wiki-insert-header-3] 982 ["Fourth level" picolisp-wiki-insert-header-4] 983 ["Fifth level" picolisp-wiki-insert-header-5] 984 ["Sixth level" picolisp-wiki-insert-header-6]) 985 "---" 986 ["Bold" picolisp-wiki-insert-bold] 987 ["Italic" picolisp-wiki-insert-italic] 988 ["Underlined" picolisp-wiki-insert-underlined] 989 ["Preformatted" picolisp-wiki-insert-pre-block] 990 ["Comment" picolisp-wiki-insert-comment] 991 ["Insert horizontal rule" picolisp-wiki-insert-hr] 992 "---" 993 ["Insert internal link" picolisp-wiki-insert-internal-link] 994 ["Insert external link" picolisp-wiki-insert-external-link] 995 "---" 996 ["Insert left-floating content" picolisp-wiki-insert-left-floating-content] 997 ["Insert non-floating content" picolisp-wiki-insert-non-floating-content] 998 ["Insert right-floating content" picolisp-wiki-insert-right-floating-content] 999 "---" 1000 ["Insert unordered list" picolisp-wiki-insert-unordered-list] 1001 ["Insert ordered list" picolisp-wiki-insert-ordered-list] 1002 "---" 1003 ["Version" picolisp-wiki-show-version] 1004 )) 1005 1006 1007 1008 ;;; Outline =================================================================== 1009 1010 ;; The following visibility cycling code was taken from org-mode 1011 ;; by Carsten Dominik and adapted for picolisp-wiki-mode. 1012 1013 (defvar picolisp-wiki-cycle-global-status 1) 1014 (defvar picolisp-wiki-cycle-subtree-status nil) 1015 1016 ;; Based on org-end-of-subtree from org.el 1017 (defun picolisp-wiki-end-of-subtree (&optional invisible-OK) 1018 "Move to the end of the current subtree. 1019 Only visible heading lines are considered, unless INVISIBLE-OK is 1020 non-nil." 1021 (outline-back-to-heading invisible-OK) 1022 (let ((first t) 1023 (level (funcall outline-level))) 1024 (while (and (not (eobp)) 1025 (or first (> (funcall outline-level) level))) 1026 (setq first nil) 1027 (outline-next-heading)) 1028 (if (memq (preceding-char) '(?\n ?\^M)) 1029 (progn 1030 ;; Go to end of line before heading 1031 (forward-char -1) 1032 (if (memq (preceding-char) '(?\n ?\^M)) 1033 ;; leave blank line before heading 1034 (forward-char -1))))) 1035 (point)) 1036 1037 ;; Based on org-cycle from org.el. 1038 (defun picolisp-wiki-cycle (&optional arg) 1039 "Visibility cycling for Picolisp-Wiki mode. 1040 If ARG is t, perform global visibility cycling. If the point is 1041 at an picolisp-wiki-style header, cycle visibility of the 1042 corresponding subtree. Otherwise, insert a tab using 1043 `indent-relative'." 1044 (interactive "P") 1045 (cond 1046 ((eq arg t) ;; Global cycling 1047 (cond 1048 ((and (eq last-command this-command) 1049 (eq picolisp-wiki-cycle-global-status 2)) 1050 ;; Move from overview to contents 1051 (hide-sublevels 1) 1052 (message "CONTENTS") 1053 (setq picolisp-wiki-cycle-global-status 3)) 1054 1055 ((and (eq last-command this-command) 1056 (eq picolisp-wiki-cycle-global-status 3)) 1057 ;; Move from contents to all 1058 (show-all) 1059 (message "SHOW ALL") 1060 (setq picolisp-wiki-cycle-global-status 1)) 1061 1062 (t 1063 ;; Defaults to overview 1064 (hide-body) 1065 (message "OVERVIEW") 1066 (setq picolisp-wiki-cycle-global-status 2)))) 1067 1068 ((save-excursion (beginning-of-line 1) (looking-at outline-regexp)) 1069 ;; At a heading: rotate between three different views 1070 (outline-back-to-heading) 1071 (let ((goal-column 0) eoh eol eos) 1072 ;; Determine boundaries 1073 (save-excursion 1074 (outline-back-to-heading) 1075 (save-excursion 1076 (beginning-of-line 2) 1077 (while (and (not (eobp)) ;; this is like `next-line' 1078 (get-char-property (1- (point)) 'invisible)) 1079 (beginning-of-line 2)) (setq eol (point))) 1080 (outline-end-of-heading) (setq eoh (point)) 1081 (picolisp-wiki-end-of-subtree t) 1082 (skip-chars-forward " \t\n") 1083 (beginning-of-line 1) ; in case this is an item 1084 (setq eos (1- (point)))) 1085 ;; Find out what to do next and set `this-command' 1086 (cond 1087 ((= eos eoh) 1088 ;; Nothing is hidden behind this heading 1089 (message "EMPTY ENTRY") 1090 (setq picolisp-wiki-cycle-subtree-status nil)) 1091 ((>= eol eos) 1092 ;; Entire subtree is hidden in one line: open it 1093 (show-entry) 1094 (show-children) 1095 (message "CHILDREN") 1096 (setq picolisp-wiki-cycle-subtree-status 'children)) 1097 ((and (eq last-command this-command) 1098 (eq picolisp-wiki-cycle-subtree-status 'children)) 1099 ;; We just showed the children, now show everything. 1100 (show-subtree) 1101 (message "SUBTREE") 1102 (setq picolisp-wiki-cycle-subtree-status 'subtree)) 1103 (t 1104 ;; Default action: hide the subtree. 1105 (hide-subtree) 1106 (message "FOLDED") 1107 (setq picolisp-wiki-cycle-subtree-status 'folded))))) 1108 1109 (t 1110 (indent-for-tab-command)))) 1111 1112 ;; Based on org-shifttab from org.el. 1113 (defun picolisp-wiki-shifttab () 1114 "Global visibility cycling. 1115 Calls `picolisp-wiki-cycle' with argument t." 1116 (interactive) 1117 (picolisp-wiki-cycle t)) 1118 1119 1120 ;;; Miscellaneous ============================================================= 1121 1122 (defun picolisp-wiki-line-number-at-pos (&optional pos) 1123 "Return (narrowed) buffer line number at position POS. 1124 If POS is nil, use current buffer location. 1125 This is an exact copy of `line-number-at-pos' for use in emacs21." 1126 (let ((opoint (or pos (point))) start) 1127 (save-excursion 1128 (goto-char (point-min)) 1129 (setq start (point)) 1130 (goto-char opoint) 1131 (forward-line 0) 1132 (1+ (count-lines start (point)))))) 1133 1134 (defun picolisp-wiki-nobreak-p () 1135 "Return nil if it is acceptable to break the current line at the point." 1136 ;; inside in square brackets (e.g., link anchor text) 1137 (looking-back "\\[[^]]*")) 1138 1139 1140 1141 ;;; Mode definition ========================================================== 1142 1143 (defun picolisp-wiki-show-version () 1144 "Show the version number in the minibuffer." 1145 (interactive) 1146 (message "picolisp-wiki-mode, version %s" picolisp-wiki-mode-version)) 1147 1148 ;;;###autoload 1149 (define-derived-mode picolisp-wiki-mode text-mode "PicoLisp-Wiki" 1150 "Major mode for editing PicoLisp-Wiki files." 1151 ;; Natural Picolisp-Wiki tab width 1152 (setq tab-width 4) 1153 ;; Comments 1154 (make-local-variable 'comment-start) 1155 (setq comment-start "#{") 1156 (make-local-variable 'comment-end) 1157 (setq comment-end "}") 1158 ;; (make-local-variable 'comment-start-skip) 1159 ;; (setq comment-start-skip "#{ \t}*") 1160 (make-local-variable 'comment-column) 1161 (setq comment-column 0) 1162 ;; Font lock. 1163 (set (make-local-variable 'font-lock-defaults) 1164 '(picolisp-wiki-mode-font-lock-keywords)) 1165 (set (make-local-variable 'font-lock-multiline) t) 1166 ;; Make filling work with lists (unordered, ordered, and definition) 1167 ;; (set (make-local-variable 'paragraph-start) 1168 ;; "\f\\|[ \t]*$\\|^[ \t]*[*+-] \\|^[ \t*][0-9]+\\.\\|^[ \t]*: ") 1169 ;; Outline mode 1170 (make-local-variable 'eval) 1171 (setq eval (outline-minor-mode)) 1172 (make-local-variable 'outline-regexp) 1173 ;; (setq outline-regexp "^[ \t]*[0-9]{") 1174 (setq outline-regexp 1175 "^[ ]*\\(1{\\|2{.\\|3{..\\|4{...\\|5{....\\|6{.....\\)") 1176 ;; Cause use of ellipses for invisible text. 1177 (add-to-invisibility-spec '(outline . t))) 1178 1179 1180 (provide 'picolisp-wiki-mode) 1181 1182 ;;; picolisp-wiki-mode.el ends here