int current_column (struct buffer *buf) { if (buf == last_known_column_buffer && BUF_PT (buf) == last_known_column_point && BUF_MODIFF (buf) == last_known_column_modified) return last_known_column; return column_at_point (buf, BUF_PT (buf), 1); }
void unlock_all_files (void) { register Lisp_Object tail; register struct buffer *b; for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) { b = XBUFFER (XCDR (XCAR (tail))); if (STRINGP (BVAR (b, file_truename)) && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) { unlock_file (BVAR (b, file_truename)); } } }
int column_at_point (struct buffer *buf, Bufpos init_pos, int cur_col) { int col; int tab_seen; int tab_width = XINT (buf->tab_width); int post_tab; Bufpos pos = init_pos; Emchar c; if (tab_width <= 0 || tab_width > 1000) tab_width = 8; col = tab_seen = post_tab = 0; while (1) { if (pos <= BUF_BEGV (buf)) break; pos--; c = BUF_FETCH_CHAR (buf, pos); if (c == '\t') { if (tab_seen) col = ((col + tab_width) / tab_width) * tab_width; post_tab += col; col = 0; tab_seen = 1; } else if (c == '\n' || (EQ (buf->selective_display, Qt) && c == '\r')) break; else { /* #### This needs updating to handle the new redisplay. */ /* #### FSFmacs looks at ctl_arrow, display tables. We need to do similar. */ #if 0 displayed_glyphs = glyphs_from_bufpos (sel_frame, buf, XWINDOW (selected_window), pos, dp, 0, col, 0, 0, 0); col += (displayed_glyphs->columns - (displayed_glyphs->begin_columns + displayed_glyphs->end_columns)); #else /* XEmacs */ #ifdef MULE col += CHAR_COLUMNS (c); #else col ++; #endif /* MULE */ #endif /* XEmacs */ } } if (tab_seen) { col = ((col + tab_width) / tab_width) * tab_width; col += post_tab; } if (cur_col) { last_known_column_buffer = buf; last_known_column = col; last_known_column_point = init_pos; last_known_column_modified = BUF_MODIFF (buf); } return col; }
EMACS_INT buf_bytepos_to_charpos (struct buffer *b, EMACS_INT bytepos) { struct Lisp_Marker *tail; EMACS_INT best_above, best_above_byte; EMACS_INT best_below, best_below_byte; if (bytepos < BUF_BEG_BYTE (b) || bytepos > BUF_Z_BYTE (b)) abort (); best_above = BUF_Z (b); best_above_byte = BUF_Z_BYTE (b); /* If this buffer has as many characters as bytes, each character must be one byte. This takes care of the case where enable-multibyte-characters is nil. */ if (best_above == best_above_byte) return bytepos; best_below = BEG; best_below_byte = BEG_BYTE; CONSIDER (BUF_PT_BYTE (b), BUF_PT (b)); CONSIDER (BUF_GPT_BYTE (b), BUF_GPT (b)); CONSIDER (BUF_BEGV_BYTE (b), BUF_BEGV (b)); CONSIDER (BUF_ZV_BYTE (b), BUF_ZV (b)); if (b == cached_buffer && BUF_MODIFF (b) == cached_modiff) CONSIDER (cached_bytepos, cached_charpos); for (tail = BUF_MARKERS (b); tail; tail = tail->next) { CONSIDER (tail->bytepos, tail->charpos); /* If we are down to a range of 50 chars, don't bother checking any other markers; scan the intervening chars directly now. */ if (best_above - best_below < 50) break; } /* We get here if we did not exactly hit one of the known places. We have one known above and one known below. Scan, counting characters, from whichever one is closer. */ if (bytepos - best_below_byte < best_above_byte - bytepos) { int record = bytepos - best_below_byte > 5000; while (best_below_byte < bytepos) { best_below++; BUF_INC_POS (b, best_below_byte); } /* If this position is quite far from the nearest known position, cache the correspondence by creating a marker here. It will last until the next GC. But don't do it if BUF_MARKERS is nil; that is a signal from Fset_buffer_multibyte. */ if (record && BUF_MARKERS (b)) { Lisp_Object marker, buffer; marker = Fmake_marker (); XSETBUFFER (buffer, b); set_marker_both (marker, buffer, best_below, best_below_byte); } if (byte_debug_flag) byte_char_debug_check (b, best_below, bytepos); cached_buffer = b; cached_modiff = BUF_MODIFF (b); cached_charpos = best_below; cached_bytepos = best_below_byte; return best_below; } else { int record = best_above_byte - bytepos > 5000; while (best_above_byte > bytepos) { best_above--; BUF_DEC_POS (b, best_above_byte); } /* If this position is quite far from the nearest known position, cache the correspondence by creating a marker here. It will last until the next GC. But don't do it if BUF_MARKERS is nil; that is a signal from Fset_buffer_multibyte. */ if (record && BUF_MARKERS (b)) { Lisp_Object marker, buffer; marker = Fmake_marker (); XSETBUFFER (buffer, b); set_marker_both (marker, buffer, best_above, best_above_byte); } if (byte_debug_flag) byte_char_debug_check (b, best_above, bytepos); cached_buffer = b; cached_modiff = BUF_MODIFF (b); cached_charpos = best_above; cached_bytepos = best_above_byte; return best_above; } }
ptrdiff_t buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos) { struct Lisp_Marker *tail; ptrdiff_t best_above, best_above_byte; ptrdiff_t best_below, best_below_byte; eassert (BUF_BEG (b) <= charpos && charpos <= BUF_Z (b)); best_above = BUF_Z (b); best_above_byte = BUF_Z_BYTE (b); /* If this buffer has as many characters as bytes, each character must be one byte. This takes care of the case where enable-multibyte-characters is nil. */ if (best_above == best_above_byte) return charpos; best_below = BEG; best_below_byte = BEG_BYTE; /* We find in best_above and best_above_byte the closest known point above CHARPOS, and in best_below and best_below_byte the closest known point below CHARPOS, If at any point we can tell that the space between those two best approximations is all single-byte, we interpolate the result immediately. */ CONSIDER (BUF_PT (b), BUF_PT_BYTE (b)); CONSIDER (BUF_GPT (b), BUF_GPT_BYTE (b)); CONSIDER (BUF_BEGV (b), BUF_BEGV_BYTE (b)); CONSIDER (BUF_ZV (b), BUF_ZV_BYTE (b)); if (b == cached_buffer && BUF_MODIFF (b) == cached_modiff) CONSIDER (cached_charpos, cached_bytepos); for (tail = BUF_MARKERS (b); tail; tail = tail->next) { CONSIDER (tail->charpos, tail->bytepos); /* If we are down to a range of 50 chars, don't bother checking any other markers; scan the intervening chars directly now. */ if (best_above - best_below < 50) break; } /* We get here if we did not exactly hit one of the known places. We have one known above and one known below. Scan, counting characters, from whichever one is closer. */ if (charpos - best_below < best_above - charpos) { bool record = charpos - best_below > 5000; while (best_below != charpos) { best_below++; BUF_INC_POS (b, best_below_byte); } /* If this position is quite far from the nearest known position, cache the correspondence by creating a marker here. It will last until the next GC. */ if (record) build_marker (b, best_below, best_below_byte); byte_char_debug_check (b, best_below, best_below_byte); cached_buffer = b; cached_modiff = BUF_MODIFF (b); cached_charpos = best_below; cached_bytepos = best_below_byte; return best_below_byte; } else { bool record = best_above - charpos > 5000; while (best_above != charpos) { best_above--; BUF_DEC_POS (b, best_above_byte); } /* If this position is quite far from the nearest known position, cache the correspondence by creating a marker here. It will last until the next GC. */ if (record) build_marker (b, best_above, best_above_byte); byte_char_debug_check (b, best_above, best_above_byte); cached_buffer = b; cached_modiff = BUF_MODIFF (b); cached_charpos = best_above; cached_bytepos = best_above_byte; return best_above_byte; } }
++pos; } } DEFUN("expand-abbrev", Fexpand_abbrev, 0, 0, "", /* Expand the abbrev before point, if any. Effective when explicitly called even when `abbrev-mode' is nil. Returns the abbrev symbol, if expansion took place. If no abbrev matched, but `pre-abbrev-expand-hook' changed the buffer, returns t. */ ()) { /* This function can GC */ struct buffer *buf = current_buffer; int oldmodiff = BUF_MODIFF(buf); Lisp_Object pre_modiff_p; Bufpos point; /* position of point */ Bufpos abbrev_start; /* position of abbreviation beginning */ Lisp_Symbol *(*fun) (struct buffer *, Lisp_Object); Lisp_Symbol *abbrev_symbol; Lisp_String *abbrev_string; Lisp_Object expansion, count, hook; Charcount abbrev_length; int lccount, uccount; run_hook(Qpre_abbrev_expand_hook); /* If the hook changes the buffer, treat that as having "done an expansion". */