PageRenderTime 54ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/editor/Buffer.cs

http://github.com/toshok/shelisp
C# | 1140 lines | 702 code | 184 blank | 254 comment | 40 complexity | cece8a07ea83130cb78636b2d1355fd3 MD5 | raw file
Possible License(s): GPL-3.0
  1. using System;
  2. using Shelisp;
  3. namespace Shemacs.Editor {
  4. class RegionCache { }
  5. class Window { }
  6. class Overlay { }
  7. class BufferText {
  8. public const int BEG = 1;
  9. public BufferText ()
  10. {
  11. gap_size = 20;
  12. #if notyet
  13. BLOCK_INPUT;
  14. /* We allocate extra 1-byte at the tail and keep it always '\0' for
  15. anchoring a search. */
  16. alloc_buffer_text (b, BUF_GAP_SIZE (b) + 1);
  17. UNBLOCK_INPUT;
  18. if (! BUF_BEG_ADDR (b))
  19. buffer_memory_full (BUF_GAP_SIZE (b) + 1);
  20. #endif
  21. gpt = BEG;
  22. gpt_byte = BEG;
  23. #if notyet
  24. *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */
  25. #endif
  26. inhibit_shrinking = 0;
  27. z = BEG;
  28. z_byte = BEG;
  29. modiff = 1;
  30. chars_modiff = 1;
  31. overlay_modiff = 1;
  32. save_modiff = 1;
  33. #if notyet
  34. intervals = 0;
  35. #endif
  36. unchanged_modified = 1;
  37. overlay_unchanged_modified = 1;
  38. end_unchanged = 0;
  39. beg_unchanged = 0;
  40. markers = null;
  41. }
  42. #if notyet
  43. /* Actual address of buffer contents. If REL_ALLOC is defined,
  44. this address might change when blocks are relocated which can
  45. e.g. happen when malloc is called. So, don't pass a pointer
  46. into a buffer's text to functions that malloc. */
  47. public byte *beg;
  48. #endif
  49. public int gpt; /* Char pos of gap in buffer. */
  50. public int z; /* Char pos of end of buffer. */
  51. public int gpt_byte; /* Byte pos of gap in buffer. */
  52. public int z_byte; /* Byte pos of end of buffer. */
  53. public int gap_size; /* Size of buffer's gap. */
  54. public int modiff; /* This counts buffer-modification events
  55. for this buffer. It is incremented for
  56. each such event, and never otherwise
  57. changed. */
  58. public int chars_modiff; /* This is modified with character change
  59. events for this buffer. It is set to
  60. modiff for each such event, and never
  61. otherwise changed. */
  62. public int save_modiff; /* Previous value of modiff, as of last
  63. time buffer visited or saved a file. */
  64. public int overlay_modiff; /* Counts modifications to overlays. */
  65. /* Minimum value of GPT - BEG since last redisplay that finished. */
  66. public int beg_unchanged;
  67. /* Minimum value of Z - GPT since last redisplay that finished. */
  68. public int end_unchanged;
  69. /* MODIFF as of last redisplay that finished; if it matches MODIFF,
  70. beg_unchanged and end_unchanged contain no useful information. */
  71. public int unchanged_modified;
  72. /* BUF_OVERLAY_MODIFF of current buffer, as of last redisplay that
  73. finished; if it matches BUF_OVERLAY_MODIFF, beg_unchanged and
  74. end_unchanged contain no useful information. */
  75. public int overlay_unchanged_modified;
  76. #if notyet
  77. /* Properties of this buffer's text. */
  78. public INTERVAL intervals;
  79. #endif
  80. /* The markers that refer to this buffer.
  81. This is actually a single marker ---
  82. successive elements in its marker `chain'
  83. are the other markers referring to this buffer.
  84. This is a singly linked unordered list, which means that it's
  85. very cheap to add a marker to the list and it's also very cheap
  86. to move a marker within a buffer. */
  87. public Marker markers;
  88. /* Usually 0. Temporarily set to 1 in decode_coding_gap to
  89. prevent Fgarbage_collect from shrinking the gap and losing
  90. not-yet-decoded bytes. */
  91. public int inhibit_shrinking;
  92. }
  93. class Buffer : Shelisp.Object {
  94. // XXX this should be a command
  95. [LispBuiltin]
  96. public static Shelisp.Object Fmake_variable_buffer_local (L l, Shelisp.Object variable)
  97. {
  98. // XXX no-op for now
  99. return variable;
  100. }
  101. [LispBuiltin (DocString = @"Return non-nil if OBJECT is a buffer which has not been killed.
  102. Value is nil if OBJECT is not a buffer or if it has been killed.")]
  103. public static Shelisp.Object Fbuffer_live_p (L l, Shelisp.Object o)
  104. {
  105. return ((o is Buffer) && !L.NILP (((Buffer)o).name)) ? L.Qt : L.Qnil;
  106. }
  107. /* Like Fassoc, but use Fstring_equal to compare
  108. (which ignores text properties),
  109. and don't ever QUIT. */
  110. static Shelisp.Object assoc_ignore_text_properties (L l, Shelisp.Object key, Shelisp.Object list) {
  111. Shelisp.Object tail;
  112. for (tail = list; L.CONSP (tail); tail = L.CDR (tail)) {
  113. Shelisp.Object elt, tem;
  114. elt = L.CAR (tail);
  115. tem = Shelisp.String.Fstring_equal (l, List.Fcar (l, elt), key);
  116. if (!L.NILP (tem))
  117. return elt;
  118. }
  119. return L.Qnil;
  120. }
  121. [LispBuiltin (DocString = @"Return the buffer named BUFFER-OR-NAME.
  122. BUFFER-OR-NAME must be either a string or a buffer. If BUFFER-OR-NAME
  123. is a string and there is no buffer with that name, return nil. If
  124. BUFFER-OR-NAME is a buffer, return it as given.")]
  125. public static Shelisp.Object Fget_buffer (L l, Shelisp.Object buffer_or_name)
  126. {
  127. if (buffer_or_name is Buffer)
  128. return buffer_or_name;
  129. //CHECK_STRING (buffer_or_name);
  130. return List.Fcdr (l, assoc_ignore_text_properties (l, buffer_or_name, Buffer.Vbuffer_alist));
  131. }
  132. [LispBuiltin (DocString = @"Return the buffer specified by BUFFER-OR-NAME, creating a new one if needed.
  133. If BUFFER-OR-NAME is a string and a live buffer with that name exists,
  134. return that buffer. If no such buffer exists, create a new buffer with
  135. that name and return it. If BUFFER-OR-NAME starts with a space, the new
  136. buffer does not keep undo information.
  137. If BUFFER-OR-NAME is a buffer instead of a string, return it as given,
  138. even if it is dead. The return value is never nil.")]
  139. public static Shelisp.Object Fget_buffer_create (L l, Shelisp.Object buffer_or_name)
  140. {
  141. Shelisp.Object buffer;
  142. buffer = Fget_buffer (l, buffer_or_name);
  143. if (!L.NILP (buffer))
  144. return buffer;
  145. if (buffer_or_name is Shelisp.String) {
  146. string name = (Shelisp.String)buffer_or_name;
  147. if (name.Length == 0)
  148. throw new Exception ("Empty string for buffer name is not allowed");
  149. buffer = new Buffer(name);
  150. }
  151. else
  152. throw new Exception ();
  153. Buffer buf = (Buffer)buffer;
  154. /* Put this on the chain of all buffers including killed ones. */
  155. buf.next = all_buffers;
  156. all_buffers = buf;
  157. /* Put this in the alist of all live buffers. */
  158. Buffer.Vbuffer_alist = List.Fnconc (l,
  159. Buffer.Vbuffer_alist,
  160. new List (new List (buf.name, buffer), L.Qnil));
  161. #if notyet
  162. /* And run buffer-list-update-hook. */
  163. if (!L.NILP (L.Vrun_hooks))
  164. L.call (L.Vrun_hooks, L.Qbuffer_list_update_hook);
  165. /* An error in calling the function here (should someone redefine it)
  166. can lead to infinite regress until you run out of stack. rms
  167. says that's not worth protecting against. */
  168. if (!L.NILP (L.Ffboundp (L.Qucs_set_table_for_input)))
  169. /* buffer is on buffer-alist, so no gcpro. */
  170. L.call (L.Qucs_set_table_for_input, buf);
  171. #endif
  172. return buffer;
  173. }
  174. [LispBuiltin]
  175. public static Shelisp.Object Fset_buffer (L l, Shelisp.Object buffer_or_name)
  176. {
  177. Shelisp.Object buf = Fget_buffer (l, buffer_or_name);
  178. if (L.NILP (buf))
  179. throw new Exception ("unknown buffer");
  180. Buffer.SetBuffer ((Buffer)buf);
  181. return buf;
  182. }
  183. [LispBuiltin (DocString = @"Return a list of all existing live buffers.
  184. If the optional arg FRAME is a frame, we return the buffer list in the
  185. proper order for that frame: the buffers show in FRAME come first,
  186. followed by the rest of the buffers.")]
  187. public static Shelisp.Object Fbuffer_list (L l, [LispOptional] Shelisp.Object frame)
  188. {
  189. #if emacs_impl
  190. Lisp.Object general = List.Fmapcar (L.Qcdr, L.Vbuffer_alist);
  191. if (L.FRAMEP (frame)) {
  192. Lisp.Object framelist, prevlist, tail;
  193. //CHECK_FRAME (frame);
  194. framelist = L.Fcopy_sequence (L.XFRAME (frame).buffer_list);
  195. prevlist = L.Fnreverse (L.Fcopy_sequence,
  196. (L.XFRAME (frame).buried_buffer_list));
  197. /* Remove from GENERAL any buffer that duplicates one in
  198. FRAMELIST or PREVLIST. */
  199. tail = framelist;
  200. while (L.CONSP (tail)) {
  201. general = L.Fdelq (L.XCAR (tail), general);
  202. tail = L.XCDR (tail);
  203. }
  204. tail = prevlist;
  205. while (L.CONSP (tail)) {
  206. general = L.Fdelq (L.XCAR (tail), general);
  207. tail = L.XCDR (tail);
  208. }
  209. return L.Fnconc (new Lisp.Object[] {
  210. framelist,
  211. general,
  212. prevlist
  213. });
  214. }
  215. else
  216. return general;
  217. #else
  218. Console.WriteLine ("buffer-list is not implemented"); return L.Qnil;
  219. #endif
  220. }
  221. #if notyet
  222. public static Func<Lisp.Object,Lisp.Object> Fget_file_buffer;
  223. public static Lisp.Subr Sget_file_buffer = L.DEFUN<Lisp.Object,Lisp.Object> (lisp_name: "get-file-buffer",
  224. doc: "Return the buffer visiting file FILENAME (a string)." +
  225. " The buffer's `buffer-file-name' must match exactly the expansion of FILENAME." +
  226. " If there is no such live buffer, return nil." +
  227. " See also `find-buffer-visiting'.",
  228. min_args: 1,
  229. func: Fget_file_buffer = (Lisp.Object filename) => {
  230. Lisp.Object tail, buf, tem;
  231. Lisp.Object handler;
  232. //CHECK_STRING (filename);
  233. filename = L.Fexpand_file_name (filename, L.Qnil);
  234. /* If the file name has special constructs in it,
  235. call the corresponding file handler. */
  236. handler = L.Ffind_file_name_handler (filename, L.Qget_file_buffer);
  237. if (!L.NILP (handler)) {
  238. Lisp.Object handled_buf = L.call (handler, L.Qget_file_buffer, filename);
  239. return L.BUFFERP (handled_buf) ? handled_buf : L.Qnil;
  240. }
  241. for (tail = L.Vbuffer_alist; L.CONSP (tail); tail = L.XCDR (tail)) {
  242. buf = List.Fcdr (L.XCAR (tail));
  243. if (!L.BUFFERP (buf)) continue;
  244. if (!L.STRINGP (L.XBUFFER(buf).filename)) continue;
  245. tem = L.Fstring_equal (L.XBUFFER(buf).filename, filename);
  246. if (!L.NILP (tem))
  247. return buf;
  248. }
  249. return L.Qnil;
  250. });
  251. public static Func<Lisp.Object,Lisp.Object> Fget_buffer_create;
  252. public static Lisp.Subr Sget_buffer_create = L.DEFUN<Lisp.Object,Lisp.Object> (lisp_name: "get-buffer-create",
  253. doc: "Return the buffer specified by BUFFER-OR-NAME, creating a new one if needed." +
  254. " If BUFFER-OR-NAME is a string and a live buffer with that name exists," +
  255. " return that buffer. If no such buffer exists, create a new buffer with" +
  256. " that name and return it. If BUFFER-OR-NAME starts with a space, the new" +
  257. " buffer does not keep undo information." +
  258. " If BUFFER-OR-NAME is a buffer instead of a string, return it as given," +
  259. " even if it is dead. The return value is never nil.",
  260. min_args: 1,
  261. func: Fget_buffer_create = (Lisp.Object buffer_or_name) => {
  262. Lisp.Object buffer, name;
  263. Buffer b;
  264. buffer = Fget_buffer (buffer_or_name);
  265. if (!L.NILP (buffer))
  266. return buffer;
  267. #if notyet
  268. if (L.SCHARS (buffer_or_name) == 0)
  269. error ("Empty string for buffer name is not allowed");
  270. #endif
  271. name = L.Fcopy_sequence (buffer_or_name);
  272. #if notyet
  273. STRING_SET_INTERVALS (name, NULL_INTERVAL);
  274. #endif
  275. b = new Buffer(name);
  276. #if notyet
  277. /* Put this on the chain of all buffers including killed ones. */
  278. b->header.next.buffer = all_buffers;
  279. all_buffers = b;
  280. #endif
  281. /* Put this in the alist of all live buffers. */
  282. L.XSETBUFFER (buffer, b);
  283. L.Vbuffer_alist = L.Fnconc (new Lisp.Object[] {
  284. L.Vbuffer_alist,
  285. L.Fcons (L.Fcons (name, buffer), L.Qnil)
  286. });
  287. /* And run buffer-list-update-hook. */
  288. if (!L.NILP (L.Vrun_hooks))
  289. L.call (L.Vrun_hooks, L.Qbuffer_list_update_hook);
  290. /* An error in calling the function here (should someone redefine it)
  291. can lead to infinite regress until you run out of stack. rms
  292. says that's not worth protecting against. */
  293. if (!L.NILP (L.Ffboundp (L.Qucs_set_table_for_input)))
  294. /* buffer is on buffer-alist, so no gcpro. */
  295. L.call (L.Qucs_set_table_for_input, buffer);
  296. return buffer;
  297. });
  298. public static Func<Lisp.Object,Lisp.Object,Lisp.Object,Lisp.Object> Fmake_indirect_buffer;
  299. public static Lisp.Subr Smake_indirect_buffer = L.DEFUN<Lisp.Object,Lisp.Object,Lisp.Object,Lisp.Object> (lisp_name: "make-indirect-buffer",
  300. min_args: 2,
  301. doc: "Create and return an indirect buffer for buffer BASE-BUFFER, named NAME." +
  302. " BASE-BUFFER should be a live buffer, or the name of an existing buffer." +
  303. " NAME should be a string which is not the name of an existing buffer." +
  304. " Optional argument CLONE non-nil means preserve BASE-BUFFER's state," +
  305. " such as major and minor modes, in the indirect buffer." +
  306. " CLONE nil means the indirect buffer's state is reset to default values.",
  307. func: Fmake_indirect_buffer = (Lisp.Object base_buffer, Lisp.Object name, Lisp.Object clone) => {
  308. Lisp.Object buf, tem;
  309. Buffer b;
  310. //CHECK_STRING (name);
  311. buf = Fget_buffer (name);
  312. #if notyet
  313. if (!L.NILP (buf))
  314. error ("Buffer name `%s' is in use", L.SDATA (name));
  315. #endif
  316. tem = base_buffer;
  317. base_buffer = Fget_buffer (base_buffer);
  318. #if notyet
  319. if (L.NILP (base_buffer))
  320. error ("No such buffer: `%s'", SDATA (tem));
  321. if (L.NILP (L.XBUFFER (base_buffer).name))
  322. error ("Base buffer has been killed");
  323. if (L.SCHARS (name) == 0)
  324. error ("Empty string for buffer name is not allowed");
  325. #endif
  326. name = L.Fcopy_sequence (name);
  327. #if notyet
  328. STRING_SET_INTERVALS (name, NULL_INTERVAL);
  329. #endif
  330. b = new Buffer (name, base_buffer);
  331. #if notyet
  332. /* Put this on the chain of all buffers including killed ones. */
  333. b->header.next.buffer = all_buffers;
  334. all_buffers = b;
  335. #endif
  336. /* Put this in the alist of all live buffers. */
  337. L.XSETBUFFER (buf, b);
  338. L.Vbuffer_alist = L.Fnconc (new Lisp.Object[] {
  339. L.Vbuffer_alist,
  340. L.Fcons (L.Fcons (name, buf), L.Qnil)
  341. });
  342. if (L.NILP (clone)) {
  343. /* Give the indirect buffer markers for its narrowing. */
  344. b.pt_marker = L.Fmake_marker ();
  345. Marker.SetBoth (b.pt_marker, buf, b.pt, b.pt_byte);
  346. b.begv_marker = L.Fmake_marker ();
  347. Marker.SetBoth (b.begv_marker, buf, b.begv, b.begv_byte);
  348. b.zv_marker = L.Fmake_marker ();
  349. Marker.SetBoth (b.zv_marker, buf, b.zv, b.zv_byte);
  350. L.XMARKER (b.zv_marker).insertion_type = 1;
  351. }
  352. else {
  353. Buffer old_b = Buffer.CurrentBuffer;
  354. b.ClonePerBufferValues (b.base_buffer);
  355. b.filename = L.Qnil;
  356. b.file_truename = L.Qnil;
  357. b.display_count = 0;
  358. b.backed_up = L.Qnil;
  359. b.auto_save_file_name = L.Qnil;
  360. SetBuffer_1 (b);
  361. L.Fset (L.intern ("buffer-save-without-query"), L.Qnil);
  362. L.Fset (L.intern ("buffer-file-number"), L.Qnil);
  363. L.Fset (L.intern ("buffer-stale-function"), L.Qnil);
  364. SetBuffer_1 (old_b);
  365. }
  366. /* Run buffer-list-update-hook. */
  367. if (!L.NILP (L.Vrun_hooks))
  368. L.call (L.Vrun_hooks, L.Qbuffer_list_update_hook);
  369. return buf;
  370. });
  371. #endif
  372. public Buffer (Shelisp.Object name, Shelisp.Object buffer)
  373. {
  374. this.base_buffer = (((Buffer)buffer).base_buffer != null
  375. ? ((Buffer)buffer).base_buffer
  376. : ((Buffer)buffer));
  377. /* Use the base buffer's text object. */
  378. text = base_buffer.text;
  379. pt = base_buffer.pt;
  380. begv = base_buffer.begv;
  381. zv = base_buffer.zv;
  382. pt_byte = base_buffer.pt_byte;
  383. begv_byte = base_buffer.begv_byte;
  384. zv_byte = base_buffer.zv_byte;
  385. #if notyet
  386. newline_cache = 0;
  387. width_run_cache = 0;
  388. #endif
  389. width_table = L.Qnil;
  390. Reset ();
  391. ResetLocalVariables (permanent_too: true);
  392. mark = new Marker ();
  393. this.name = name;
  394. /* The multibyte status belongs to the base buffer. */
  395. enable_multibyte_characters = base_buffer.enable_multibyte_characters;
  396. /* Make sure the base buffer has markers for its narrowing. */
  397. if (L.NILP (base_buffer.pt_marker)) {
  398. #if notyet
  399. eassert (NILP (BVAR (base_buffer, begv_marker)));
  400. eassert (NILP (BVAR (base_buffer, zv_marker)));
  401. #endif
  402. base_buffer.pt_marker = new Marker ();
  403. Marker.SetBoth (base_buffer.pt_marker, buffer,
  404. base_buffer.pt,
  405. base_buffer.pt_byte);
  406. base_buffer.begv_marker = new Marker ();
  407. Marker.SetBoth (base_buffer.begv_marker, buffer,
  408. base_buffer.begv,
  409. base_buffer.begv_byte);
  410. base_buffer.zv_marker = new Marker ();
  411. Marker.SetBoth (base_buffer.zv_marker, buffer,
  412. base_buffer.zv,
  413. base_buffer.zv_byte);
  414. ((Marker)base_buffer.zv_marker).Type = Marker.InsertionType.MarkerAdvancesOnTextInsertion;
  415. }
  416. }
  417. public Buffer (Shelisp.Object name)
  418. {
  419. /* An ordinary buffer uses its own struct buffer_text. */
  420. text = new BufferText();
  421. pt = BufferText.BEG;
  422. begv = BufferText.BEG;
  423. zv = BufferText.BEG;
  424. pt_byte = BufferText.BEG;
  425. begv_byte = BufferText.BEG;
  426. zv_byte = BufferText.BEG;
  427. #if notyet
  428. newline_cache = 0;
  429. width_run_cache = 0;
  430. #endif
  431. width_table = L.Qnil;
  432. prevent_redisplay_optimizations_p = true;
  433. /* An ordinary buffer normally doesn't need markers
  434. to handle BEGV and ZV. */
  435. pt_marker = L.Qnil;
  436. begv_marker = L.Qnil;
  437. zv_marker = L.Qnil;
  438. undo_list = (L.SREF (name, 0) != ' ') ? L.Qnil : L.Qt;
  439. Reset ();
  440. ResetLocalVariables (permanent_too: true);
  441. mark = new Marker ();
  442. this.name = name;
  443. }
  444. [LispBuiltin]
  445. public static Shelisp.Object Fcurrent_buffer (L l)
  446. {
  447. return Buffer.CurrentBuffer;
  448. }
  449. public static Buffer CurrentBuffer { get; set; }
  450. public static Buffer BufferDefaults { get; set; }
  451. public static Buffer BufferLocalFlags { get; set; }
  452. public static Buffer BufferLocalSymbols { get; set; }
  453. /* Clone per-buffer values of buffer FROM.
  454. Buffer TO gets the same per-buffer values as FROM, with the
  455. following exceptions: (1) TO's name is left untouched, (2) markers
  456. are copied and made to refer to TO, and (3) overlay lists are
  457. copied. */
  458. public void ClonePerBufferValues (Buffer from)
  459. {
  460. }
  461. public void DelegateAllOverlays ()
  462. {
  463. }
  464. public void Reset ()
  465. {
  466. }
  467. public void ResetLocalVariables (bool permanent_too)
  468. {
  469. }
  470. public void EvaporateOverlays (int position)
  471. {
  472. }
  473. #if notyet
  474. extern ptrdiff_t overlays_at (int pos, int extend, Shelisp.Object **vec_ptr,
  475. ptrdiff_t *len_ptr, int *next_ptr,
  476. int *prev_ptr, int change_req);
  477. extern ptrdiff_t sort_overlays (Shelisp.Object *, ptrdiff_t, struct window *);
  478. #endif
  479. public void RecenterOverlayLists (int position)
  480. {
  481. throw new NotImplementedException ();
  482. }
  483. public int OverlayStrings (int position, Window w, out byte[] str)
  484. {
  485. throw new NotImplementedException ();
  486. }
  487. public void ValidateRegion (Shelisp.Object b, Shelisp.Object e)
  488. {
  489. throw new NotImplementedException ();
  490. }
  491. public static void SetBuffer (Buffer b)
  492. {
  493. if (CurrentBuffer != b)
  494. SetBuffer_1 (b);
  495. }
  496. public static void SetBuffer_1 (Buffer b)
  497. {
  498. Buffer.CurrentBuffer = b;
  499. }
  500. public static void RecordBuffer (Shelisp.Object buffer)
  501. {
  502. throw new NotImplementedException ();
  503. }
  504. public static void BufferSlotTypMismatch (Shelisp.Object newval, int type)
  505. {
  506. }
  507. public void FixOverlaysBefore (Buffer buffer, int prev, int pos)
  508. {
  509. }
  510. #if not_yet
  511. /* Get overlays at POSN into array OVERLAYS with NOVERLAYS elements.
  512. If NEXTP is non-NULL, return next overlay there.
  513. See overlay_at arg CHANGE_REQ for meaning of CHRQ arg. */
  514. define GET_OVERLAYS_AT(posn, overlays, noverlays, nextp, chrq) \
  515. do { \
  516. ptrdiff_t maxlen = 40; \
  517. overlays = (Shelisp.Object *) alloca (maxlen * sizeof (Shelisp.Object)); \
  518. noverlays = overlays_at (posn, 0, &overlays, &maxlen, \
  519. nextp, NULL, chrq); \
  520. if (noverlays > maxlen) \
  521. { \
  522. maxlen = noverlays; \
  523. overlays = (Shelisp.Object *) alloca (maxlen * sizeof (Shelisp.Object)); \
  524. noverlays = overlays_at (posn, 0, &overlays, &maxlen, \
  525. nextp, NULL, chrq); \
  526. } \
  527. } while (0)
  528. EXFUN (Fbuffer_live_p, 1);
  529. EXFUN (Fbuffer_name, 1);
  530. EXFUN (Fnext_overlay_change, 1);
  531. EXFUN (Fbuffer_local_value, 2);
  532. extern Shelisp.Object Qbefore_change_functions;
  533. extern Shelisp.Object Qafter_change_functions;
  534. extern Shelisp.Object Qfirst_change_hook;
  535. #endif
  536. /* This points to the text that used for this buffer.
  537. In an indirect buffer, this is a reference to the 'text' field of another buffer. */
  538. BufferText text;
  539. /* Char position of point in buffer. */
  540. int pt;
  541. /* Byte position of point in buffer. */
  542. int pt_byte;
  543. /* Char position of beginning of accessible range. */
  544. int begv;
  545. /* Byte position of beginning of accessible range. */
  546. int begv_byte;
  547. /* Char position of end of accessible range. */
  548. int zv;
  549. /* Byte position of end of accessible range. */
  550. int zv_byte;
  551. /* In an indirect buffer, this points to the base buffer.
  552. In an ordinary buffer, it is null. */
  553. Buffer base_buffer;
  554. const int MAX_PER_BUFFER_VARS = 50;
  555. byte[] local_flags = new byte[MAX_PER_BUFFER_VARS];
  556. /* Set to the modtime of the visited file when read or written.
  557. -1 means visited file was nonexistent.
  558. 0 means visited file modtime unknown; in no case complain
  559. about any mismatch on next save attempt. */
  560. DateTime modtime;
  561. /* Size of the file when modtime was set. This is used to detect the
  562. case where the file grew while we were reading it, so the modtime
  563. is still the same (since it's rounded up to seconds) but we're actually
  564. not up-to-date. -1 means the size is unknown. Only meaningful if
  565. modtime is actually set. */
  566. long modtime_size;
  567. /* The value of text->modiff at the last auto-save. */
  568. int auto_save_modified;
  569. /* The value of text->modiff at the last display error.
  570. Redisplay of this buffer is inhibited until it changes again. */
  571. int display_error_modiff;
  572. /* The time at which we detected a failure to auto-save,
  573. Or 0 if we didn't have a failure. */
  574. DateTime auto_save_failure_time;
  575. /* Position in buffer at which display started
  576. the last time this buffer was displayed. */
  577. int last_window_start;
  578. /* Set nonzero whenever the narrowing is changed in this buffer. */
  579. bool clip_changed;
  580. /* If the long line scan cache is enabled (i.e. the buffer-local
  581. variable cache-long-line-scans is non-nil), newline_cache
  582. points to the newline cache, and width_run_cache points to the
  583. width run cache.
  584. The newline cache records which stretches of the buffer are
  585. known *not* to contain newlines, so that they can be skipped
  586. quickly when we search for newlines.
  587. The width run cache records which stretches of the buffer are
  588. known to contain characters whose widths are all the same. If
  589. the width run cache maps a character to a value > 0, that value is
  590. the character's width; if it maps a character to zero, we don't
  591. know what its width is. This allows compute_motion to process
  592. such regions very quickly, using algebra instead of inspecting
  593. each character. See also width_table, below. */
  594. RegionCache newline_cache;
  595. RegionCache width_run_cache;
  596. /* true means don't use redisplay optimizations for
  597. displaying this buffer. */
  598. bool prevent_redisplay_optimizations_p;
  599. /* List of overlays that end at or before the current center,
  600. in order of end-position. */
  601. Overlay overlays_before;
  602. /* List of overlays that end after the current center,
  603. in order of start-position. */
  604. Overlay overlays_after;
  605. /* Position where the overlay lists are centered. */
  606. int overlay_center;
  607. /* Changes in the buffer are recorded here for undo.
  608. t means don't record anything.
  609. This information belongs to the base buffer of an indirect buffer,
  610. But we can't store it in the struct buffer_text
  611. because local variables have to be right in the struct buffer.
  612. So we copy it around in set_buffer_internal.
  613. This comes before `name' because it is marked in a special way. */
  614. Shelisp.Object undo_list;
  615. /* The name of this buffer. */
  616. public Shelisp.Object name;
  617. /* The name of the file visited in this buffer, or nil. */
  618. public Shelisp.Object filename = L.Qnil;
  619. [LispBuiltin]
  620. public static Shelisp.Object Vbuffer_file_name {
  621. get { return Buffer.CurrentBuffer.filename; }
  622. set { Buffer.CurrentBuffer.filename = value; }
  623. }
  624. /* Dir for expanding relative file names. */
  625. Shelisp.Object directory;
  626. /* True if this buffer has been backed up (if you write to the
  627. visited file and it hasn't been backed up, then a backup will
  628. be made). */
  629. /* This isn't really used by the C code, so could be deleted. */
  630. Shelisp.Object backed_up;
  631. /* Length of file when last read or saved.
  632. -1 means auto saving turned off because buffer shrank a lot.
  633. -2 means don't turn off auto saving if buffer shrinks.
  634. (That value is used with buffer-swap-text.)
  635. This is not in the struct buffer_text
  636. because it's not used in indirect buffers at all. */
  637. Shelisp.Object save_length;
  638. /* File name used for auto-saving this buffer.
  639. This is not in the struct buffer_text
  640. because it's not used in indirect buffers at all. */
  641. Shelisp.Object auto_save_file_name;
  642. /* Non-nil if buffer read-only. */
  643. Shelisp.Object read_only;
  644. /* "The mark". This is a marker which may
  645. point into this buffer or may point nowhere. */
  646. Shelisp.Object mark;
  647. /* Alist of elements (SYMBOL . VALUE-IN-THIS-BUFFER) for all
  648. per-buffer variables of this buffer. For locally unbound
  649. symbols, just the symbol appears as the element. */
  650. Shelisp.Object local_var_alist;
  651. /* Symbol naming major mode (eg, lisp-mode). */
  652. [LispBuiltin]
  653. public static Shelisp.Object Vmajor_mode = L.Qnil;
  654. public Shelisp.Object major_mode;
  655. /* Pretty name of major mode (eg, "Lisp"). */
  656. Shelisp.Object mode_name;
  657. /* Mode line element that controls format of mode line. */
  658. [LispBuiltin]
  659. public static Shelisp.Object Vmode_line_format = L.Qnil;
  660. public Shelisp.Object mode_line_format;
  661. /* Analogous to mode_line_format for the line displayed at the top
  662. of windows. Nil means don't display that line. */
  663. Shelisp.Object header_line_format;
  664. /* Keys that are bound local to this buffer. */
  665. Shelisp.Object keymap;
  666. /* This buffer's local abbrev table. */
  667. Shelisp.Object abbrev_table;
  668. /* This buffer's syntax table. */
  669. Shelisp.Object syntax_table;
  670. /* This buffer's category table. */
  671. Shelisp.Object category_table;
  672. /* Values of several buffer-local variables. */
  673. /* tab-width is buffer-local so that redisplay can find it
  674. in buffers that are not current. */
  675. private Shelisp.Object case_fold_search = L.Qnil;
  676. [LispBuiltin]
  677. public static Shelisp.Object Vcase_fold_search {
  678. get { return Buffer.CurrentBuffer.case_fold_search; }
  679. set { Buffer.CurrentBuffer.case_fold_search = value; }
  680. }
  681. private Shelisp.Object tab_width = L.Qnil;
  682. [LispBuiltin]
  683. public static Shelisp.Object Vtab_width {
  684. get { return Buffer.CurrentBuffer.tab_width; }
  685. set { Buffer.CurrentBuffer.tab_width = value; }
  686. }
  687. private Shelisp.Object fill_column = L.Qnil;
  688. [LispBuiltin]
  689. public static Shelisp.Object Vfill_column {
  690. get { return Buffer.CurrentBuffer.fill_column; }
  691. set { Buffer.CurrentBuffer.fill_column = value; }
  692. }
  693. private Shelisp.Object left_margin = L.Qnil;
  694. [LispBuiltin]
  695. public static Shelisp.Object Vleft_margin {
  696. get { return Buffer.CurrentBuffer.left_margin; }
  697. set { Buffer.CurrentBuffer.left_margin = value; }
  698. }
  699. /* Function to call when insert space past fill column. */
  700. Shelisp.Object auto_fill_function;
  701. /* Case table for case-conversion in this buffer.
  702. This char-table maps each char into its lower-case version. */
  703. Shelisp.Object downcase_table;
  704. /* Char-table mapping each char to its upper-case version. */
  705. Shelisp.Object upcase_table;
  706. /* Char-table for conversion for case-folding search. */
  707. Shelisp.Object case_canon_table;
  708. /* Char-table of equivalences for case-folding search. */
  709. Shelisp.Object case_eqv_table;
  710. /* Non-nil means do not display continuation lines. */
  711. private Shelisp.Object truncate_lines = L.Qnil;
  712. [LispBuiltin]
  713. public static Shelisp.Object Vtruncate_lines {
  714. get { return Buffer.CurrentBuffer.truncate_lines; }
  715. set { Buffer.CurrentBuffer.truncate_lines = value; }
  716. }
  717. /* Non-nil means to use word wrapping when displaying continuation lines. */
  718. private Shelisp.Object word_wrap = L.Qnil;
  719. [LispBuiltin]
  720. public static Shelisp.Object Vword_wrap {
  721. get { return Buffer.CurrentBuffer.word_wrap; }
  722. set { Buffer.CurrentBuffer.word_wrap = value; }
  723. }
  724. /* Non-nil means display ctl chars with uparrow. */
  725. private Shelisp.Object ctl_arrow = L.Qnil;
  726. [LispBuiltin]
  727. public static Shelisp.Object Vctl_arrow {
  728. get { return Buffer.CurrentBuffer.ctl_arrow; }
  729. set { Buffer.CurrentBuffer.ctl_arrow = value; }
  730. }
  731. /* Non-nil means reorder bidirectional text for display in the
  732. visual order. */
  733. private Shelisp.Object bidi_display_reordering = L.Qnil;
  734. [LispBuiltin]
  735. public static Shelisp.Object Vbidi_display_reordering {
  736. get { return Buffer.CurrentBuffer.bidi_display_reordering; }
  737. set { Buffer.CurrentBuffer.bidi_display_reordering = value; }
  738. }
  739. /* If non-nil, specifies which direction of text to force in all the
  740. paragraphs of the buffer. Nil means determine paragraph
  741. direction dynamically for each paragraph. */
  742. private Shelisp.Object bidi_paragraph_direction = L.Qnil;
  743. [LispBuiltin]
  744. public static Shelisp.Object Vbidi_paragraph_direction {
  745. get { return Buffer.CurrentBuffer.bidi_paragraph_direction; }
  746. set { Buffer.CurrentBuffer.bidi_paragraph_direction = value; }
  747. }
  748. /* Non-nil means do selective display;
  749. see doc string in syms_of_buffer (buffer.c) for details. */
  750. Shelisp.Object selective_display;
  751. /* Non-nil means show ... at end of line followed by invisible lines. */
  752. private Shelisp.Object selective_display_ellipses = L.Qnil;
  753. [LispBuiltin]
  754. public static Shelisp.Object Vselective_display_ellipses {
  755. get { return Buffer.CurrentBuffer.selective_display_ellipses; }
  756. set { Buffer.CurrentBuffer.selective_display_ellipses = value; }
  757. }
  758. /* Alist of (FUNCTION . STRING) for each minor mode enabled in buffer. */
  759. Shelisp.Object minor_modes;
  760. /* t if "self-insertion" should overwrite; `binary' if it should also
  761. overwrite newlines and tabs - for editing executables and the like. */
  762. Shelisp.Object overwrite_mode;
  763. /* non-nil means abbrev mode is on. Expand abbrevs automatically. */
  764. Shelisp.Object abbrev_mode;
  765. /* Display table to use for text in this buffer. */
  766. Shelisp.Object display_table;
  767. /* t means the mark and region are currently active. */
  768. Shelisp.Object mark_active;
  769. /* Non-nil means the buffer contents are regarded as multi-byte
  770. form of characters, not a binary code. */
  771. Shelisp.Object enable_multibyte_characters = L.Qt;
  772. [LispBuiltin]
  773. public static Shelisp.Object Venable_multibyte_characters {
  774. get { return Buffer.CurrentBuffer.enable_multibyte_characters; }
  775. set { Buffer.CurrentBuffer.enable_multibyte_characters = value; }
  776. }
  777. /* Coding system to be used for encoding the buffer contents on
  778. saving. */
  779. Shelisp.Object buffer_file_coding_system;
  780. /* List of symbols naming the file format used for visited file. */
  781. Shelisp.Object file_format;
  782. /* List of symbols naming the file format used for auto-save file. */
  783. Shelisp.Object auto_save_file_format;
  784. /* True if the newline position cache and width run cache are
  785. enabled. See search.c and indent.c. */
  786. Shelisp.Object cache_long_line_scans;
  787. /* If the width run cache is enabled, this table contains the
  788. character widths width_run_cache (see above) assumes. When we
  789. do a thorough redisplay, we compare this against the buffer's
  790. current display table to see whether the display table has
  791. affected the widths of any characters. If it has, we
  792. invalidate the width run cache, and re-initialize width_table. */
  793. Shelisp.Object width_table;
  794. /* In an indirect buffer, or a buffer that is the base of an
  795. indirect buffer, this holds a marker that records
  796. PT for this buffer when the buffer is not current. */
  797. Shelisp.Object pt_marker;
  798. /* In an indirect buffer, or a buffer that is the base of an
  799. indirect buffer, this holds a marker that records
  800. BEGV for this buffer when the buffer is not current. */
  801. Shelisp.Object begv_marker;
  802. /* In an indirect buffer, or a buffer that is the base of an
  803. indirect buffer, this holds a marker that records
  804. ZV for this buffer when the buffer is not current. */
  805. Shelisp.Object zv_marker;
  806. /* This holds the point value before the last scroll operation.
  807. Explicitly setting point sets this to nil. */
  808. Shelisp.Object point_before_scroll;
  809. /* Truename of the visited file, or nil. */
  810. Shelisp.Object file_truename;
  811. /* Invisibility spec of this buffer.
  812. t => any non-nil `invisible' property means invisible.
  813. A list => `invisible' property means invisible
  814. if it is memq in that list. */
  815. Shelisp.Object invisibility_spec;
  816. /* This is the last window that was selected with this buffer in it,
  817. or nil if that window no longer displays this buffer. */
  818. Shelisp.Object last_selected_window;
  819. /* Incremented each time the buffer is displayed in a window. */
  820. Shelisp.Object display_count;
  821. /* Widths of left and right marginal areas for windows displaying
  822. this buffer. */
  823. Shelisp.Object left_margin_cols, right_margin_cols;
  824. /* Widths of left and right fringe areas for windows displaying
  825. this buffer. */
  826. Shelisp.Object left_fringe_width, right_fringe_width;
  827. /* Non-nil means fringes are drawn outside display margins;
  828. othersize draw them between margin areas and text. */
  829. Shelisp.Object fringes_outside_margins;
  830. /* Width and type of scroll bar areas for windows displaying
  831. this buffer. */
  832. Shelisp.Object scroll_bar_width, vertical_scroll_bar_type;
  833. /* Non-nil means indicate lines not displaying text (in a style
  834. like vi). */
  835. private Shelisp.Object indicate_empty_lines = L.Qnil;
  836. [LispBuiltin]
  837. public static Shelisp.Object Vindicate_empty_lines {
  838. get { return Buffer.CurrentBuffer.indicate_empty_lines; }
  839. set { Buffer.CurrentBuffer.indicate_empty_lines = value; }
  840. }
  841. /* Non-nil means indicate buffer boundaries and scrolling. */
  842. private Shelisp.Object indicate_buffer_boundaries = L.Qnil;
  843. [LispBuiltin]
  844. public static Shelisp.Object Vindicate_buffer_boundaries {
  845. get { return Buffer.CurrentBuffer.indicate_buffer_boundaries; }
  846. set { Buffer.CurrentBuffer.indicate_buffer_boundaries = value; }
  847. }
  848. /* Logical to physical fringe bitmap mappings. */
  849. private Shelisp.Object fringe_indicator_alist = L.Qnil;
  850. [LispBuiltin]
  851. public static Shelisp.Object Vfringe_indicator_alist {
  852. get { return Buffer.CurrentBuffer.fringe_indicator_alist; }
  853. set { Buffer.CurrentBuffer.fringe_indicator_alist = value; }
  854. }
  855. /* Logical to physical cursor bitmap mappings. */
  856. private Shelisp.Object fringe_cursor_alist = L.Qnil;
  857. [LispBuiltin]
  858. public static Shelisp.Object Vfringe_cursor_alist {
  859. get { return Buffer.CurrentBuffer.fringe_cursor_alist; }
  860. set { Buffer.CurrentBuffer.fringe_cursor_alist = value; }
  861. }
  862. /* Time stamp updated each time this buffer is displayed in a window. */
  863. Shelisp.Object display_time;
  864. /* If scrolling the display because point is below the bottom of a
  865. window showing this buffer, try to choose a window start so
  866. that point ends up this number of lines from the top of the
  867. window. Nil means that scrolling method isn't used. */
  868. private Shelisp.Object scroll_up_aggressively = L.Qnil;
  869. [LispBuiltin]
  870. public static Shelisp.Object Vscroll_up_aggressively {
  871. get { return Buffer.CurrentBuffer.scroll_up_aggressively; }
  872. set { Buffer.CurrentBuffer.scroll_up_aggressively = value; }
  873. }
  874. /* If scrolling the display because point is above the top of a
  875. window showing this buffer, try to choose a window start so
  876. that point ends up this number of lines from the bottom of the
  877. window. Nil means that scrolling method isn't used. */
  878. private Shelisp.Object scroll_down_aggressively = L.Qnil;
  879. [LispBuiltin]
  880. public static Shelisp.Object Vscroll_down_aggressively {
  881. get { return Buffer.CurrentBuffer.scroll_down_aggressively; }
  882. set { Buffer.CurrentBuffer.scroll_down_aggressively = value; }
  883. }
  884. /* Desired cursor type in this buffer. See the doc string of
  885. per-buffer variable `cursor-type'. */
  886. private Shelisp.Object cursor_type = L.Qnil;
  887. [LispBuiltin]
  888. public static Shelisp.Object Vcursor_type {
  889. get { return Buffer.CurrentBuffer.cursor_type; }
  890. set { Buffer.CurrentBuffer.cursor_type = value; }
  891. }
  892. /* An integer > 0 means put that number of pixels below text lines
  893. in the display of this buffer. */
  894. private Shelisp.Object extra_line_spacing = L.Qnil;
  895. [LispBuiltin ("line-spacing")]
  896. public static Shelisp.Object Vextra_line_spacing {
  897. get { return Buffer.CurrentBuffer.extra_line_spacing; }
  898. set { Buffer.CurrentBuffer.extra_line_spacing = value; }
  899. }
  900. /* *Cursor type to display in non-selected windows.
  901. t means to use hollow box cursor.
  902. See `cursor-type' for other values. */
  903. private Shelisp.Object cursor_in_non_selected_windows = L.Qnil;
  904. [LispBuiltin]
  905. public static Shelisp.Object Vcursor_in_non_selected_windows {
  906. get { return Buffer.CurrentBuffer.cursor_in_non_selected_windows; }
  907. set { Buffer.CurrentBuffer.cursor_in_non_selected_windows = value; }
  908. }
  909. public Buffer next;
  910. public static Buffer all_buffers;
  911. public static Shelisp.Object Vbuffer_alist = L.Qnil;
  912. [LispBuiltin (DocString = @"Non-nil if Transient Mark mode is enabled.
  913. See the command `transient-mark-mode' for a description of this minor mode.
  914. Non-nil also enables highlighting of the region whenever the mark is active.
  915. The variable `highlight-nonselected-windows' controls whether to highlight
  916. all windows or just the selected window.
  917. Lisp programs may give this variable certain special values:
  918. - A value of `lambda' enables Transient Mark mode temporarily.
  919. It is disabled again after any subsequent action that would
  920. normally deactivate the mark (e.g. buffer modification).
  921. - A value of (only . OLDVAL) enables Transient Mark mode
  922. temporarily. After any subsequent point motion command that is
  923. not shift-translated, or any other action that would normally
  924. deactivate the mark (e.g. buffer modification), the value of
  925. `transient-mark-mode' is set to OLDVAL.")]
  926. public static Shelisp.Object Vtransient_mark_mode = L.Qnil;
  927. [LispBuiltin (DocString = @"Non-nil means you can use the mark even when inactive.
  928. This option makes a difference in Transient Mark mode.
  929. When the option is non-nil, deactivation of the mark
  930. turns off region highlighting, but commands that use the mark
  931. behave as if the mark were still active.")]
  932. public static bool Vmark_even_if_inactive = true;
  933. [LispBuiltin (DocString = @"List of functions called with no args to query before killing a buffer.
  934. The buffer being killed will be current while the functions are running.
  935. If any of them returns nil, the buffer is not killed.")]
  936. public static Shelisp.Object Vkill_buffer_query_functions = L.Qnil;
  937. }
  938. public static class PerBuffer {
  939. /* Mode line element that controls format of mode line. */
  940. public static Shelisp.Object mode_line_format {
  941. get { return Buffer.CurrentBuffer.mode_line_format; }
  942. set { Buffer.CurrentBuffer.mode_line_format = value; }
  943. }
  944. public static Shelisp.Object major_mode {
  945. get { return Buffer.CurrentBuffer.major_mode; }
  946. set { Buffer.CurrentBuffer.major_mode = value; }
  947. }
  948. }
  949. }