File indexing completed on 2024-12-29 03:43:58

0001 // Utility functions
0002 // distance - Like cursor, only absolute
0003 // interval - Like range, only absolute
0004 distanceFromCursor = function(cursor) {
0005         var pos = cursor.column;
0006         var a;
0007         for (a = 0; a < cursor.line; a++) {
0008                 pos += document.lineLength(a) + 1; //Kate normalizes newlines to \n
0009         }
0010         return pos;
0011 }
0012 
0013 intervalFromRange = function(range) {
0014         return {
0015                 start: distanceFromCursor(range.start),
0016                 end: distanceFromCursor(range.end)
0017         }
0018 }
0019 
0020 cursorFromDistance = function(distance) {
0021         var line = 0;
0022         var positionSoFar = 0;
0023         while (positionSoFar + (document.lineLength(line) + 1) <= distance) {
0024                 positionSoFar += (document.lineLength(line) + 1)
0025                 line++;
0026         }
0027         return new Cursor(line, distance - positionSoFar);
0028         
0029 }
0030 
0031 rangeFromIntervals = function(distance1, distance2) {
0032         return new Range( cursorFromDistance(distance1), cursorFromDistance(distance2) );
0033 }
0034 
0035 // Pseudo editor interface
0036 var zen_editor = function(document, view) {
0037         this.context = document;
0038         
0039         this.setContext = function(document) {
0040                 this.context = document;
0041         }
0042         
0043         
0044         /**
0045          * Returns character indexes of selected text: object with <code>start</code>
0046          * and <code>end</code> properties. If there's no selection, should return 
0047          * object with <code>start</code> and <code>end</code> properties referring
0048          * to current caret position
0049          * @return {Object}
0050          * @example
0051          * var selection = editor.getSelectionRange();
0052          * alert(selection.start + ', ' + selection.end); 
0053          */
0054         this.getSelectionRange = function() {
0055                 var returnValue
0056                 if (view.hasSelection()) {
0057                         returnValue = intervalFromRange(view.selection());
0058                 }
0059                 else {
0060                         returnValue = intervalFromRange(new Range(view.cursorPosition(), view.cursorPosition()));
0061                 }
0062                 return returnValue;
0063         }
0064         
0065         /**
0066          * Creates selection from <code>start</code> to <code>end</code> character
0067          * indexes. If <code>end</code> is ommited, this method should place caret 
0068          * and <code>start</code> index
0069          * @param {Number} start
0070          * @param {Number} [end]
0071          * @example
0072          * editor.createSelection(10, 40);
0073          * 
0074          * //move caret to 15th character
0075          * editor.createSelection(15);
0076          */
0077         this.createSelection = function(start, end) {
0078                 var selection = rangeFromIntervals(start, end);
0079                 view.setSelection(selection);
0080                 view.setCursorPosition(cursorFromDistance(end));
0081         }
0082         
0083         /**
0084          * Returns current line's start and end indexes as object with <code>start</code>
0085          * and <code>end</code> properties
0086          * @return {Object}
0087          * @example
0088          * var range = editor.getCurrentLineRange();
0089          * alert(range.start + ', ' + range.end);
0090          */
0091         this.getCurrentLineRange = function() {
0092                 var position = view.cursorPosition()
0093                 return {
0094                         start: distanceFromCursor(new Cursor(position.line, 0)),
0095                         end: distanceFromCursor(new Cursor(position.line,document.lineLength(position.line)))
0096                 };
0097         }
0098         
0099         /**
0100          * Returns current caret position
0101          * @return {Number|null}
0102          */
0103         this.getCaretPos = function(){
0104                 return distanceFromCursor(view.cursorPosition());
0105         }
0106         
0107         /**
0108          * Set new caret position
0109          * @param {Number} pos Caret position
0110          */
0111         this.setCaretPos = function(pos){
0112                 view.setCursorPosition(cursorFromDistance(pos));
0113         }
0114         
0115         /**
0116          * Returns content of current line
0117          * @return {String}
0118          */
0119         this.getCurrentLine = function() {
0120                 return document.line(view.cursorPosition().line);
0121         }
0122         
0123         /**
0124          * Replace editor's content or it's part (from <code>start</code> to 
0125          * <code>end</code> index). If <code>value</code> contains 
0126          * <code>caret_placeholder</code>, the editor will put caret into 
0127          * this position. If you skip <code>start</code> and <code>end</code>
0128          * arguments, the whole target's content will be replaced with 
0129          * <code>value</code>. 
0130          * 
0131          * If you pass <code>start</code> argument only,
0132          * the <code>value</code> will be placed at <code>start</code> string 
0133          * index of current content. 
0134          * 
0135          * If you pass <code>start</code> and <code>end</code> arguments,
0136          * the corresponding substring of current target's content will be 
0137          * replaced with <code>value</code>. 
0138          * @param {String} value Content you want to paste
0139          * @param {Number} [start] Start index of editor's content
0140          * @param {Number} [end] End index of editor's content
0141          * @param {Boolean} [no_indent] Do not auto indent <code>value</code>
0142          */
0143         this.replaceContent = function(value, start, end, no_indent) {
0144                 //handle the no indent parameter
0145                 if (!no_indent) {
0146                         var utils = emmet.require('utils');
0147                         value = utils.padString(value, utils.getLinePadding(this.getCurrentLine()));
0148                 }
0149                 
0150                 //emmet's tabstops - TODO: what would be the best way to support this in Kate?
0151                 var tabstopData = emmet.require('tabStops').extract(value, {
0152                                 escape: function(ch) {
0153                                         return ch;
0154                                 }
0155                         });
0156                 value = tabstopData.text;
0157                 var firstTabStop = tabstopData.tabstops[0];
0158                 
0159                 if (typeof(end) == 'undefined') {
0160                         if (typeof(start) == 'undefined') {
0161                                 document.setText(value);
0162                         } else {
0163                                 document.insertText(cursorFromDistance(start), value);
0164                         }
0165                 } else {
0166                         document.editBegin(); //group changes together in undo history
0167                         var docRange = rangeFromIntervals(start, end);
0168                         document.removeText(docRange);
0169                         document.insertText(docRange.start, value);
0170                         document.editEnd();
0171                 }
0172                 if (firstTabStop) this.setCaretPos(start + firstTabStop.start);
0173         }
0174         
0175         /**
0176          * Returns editor's content
0177          * @return {String}
0178          */
0179         this.getContent = function(){
0180                 return document.text();
0181         }
0182         
0183         /**
0184          * Returns current editor's syntax mode
0185          * @return {String}
0186          */
0187         this.getSyntax = function(){
0188                 var syntax = document.highlightingModeAt(view.cursorPosition()).toLowerCase();
0189                 if (syntax == 'haml with ruby') syntax = 'haml'; //fixes a common syntax highlighting verbosity
0190                 if (syntax == 'none')
0191                         syntax = 'html';
0192                 return syntax;
0193         }
0194         
0195         /**
0196          * Returns current output profile name (@see emmet#setupProfile)
0197          * @return {String}
0198          */
0199         this.getProfileName = function() {
0200                 var profile = this.getSyntax();
0201                 if (profile == 'html') {
0202                         var htmlProfile = emmet.require('resources').getVariable('profile');
0203                         if (!htmlProfile) {
0204                                 htmlProfile = this.getContent().search(/<!DOCTYPE[^>]+XHTML/i) != -1 ? 'xhtml': 'html';
0205                         }
0206                         profile = htmlProfile;
0207                 }
0208                 return profile;
0209         }
0210         
0211         /**
0212          * Ask user to enter something
0213          * @param {String} title Dialog title
0214          * @return {String} Entered data
0215          * @since 0.65
0216          */
0217         this.prompt = function(title) {
0218                 return '';
0219         }
0220         
0221         /**
0222          * Returns current selection
0223          * @return {String}
0224          * @since 0.65
0225          */
0226         this.getSelection = function() {
0227                 return view.selectedText();
0228         }
0229         
0230         /**
0231          * Returns current editor's file path
0232          * @return {String}
0233          * @since 0.65 
0234          */
0235         this.getFilePath = function() {
0236                 return document.url(); //or would document.fileName() be better?
0237         }
0238         
0239 }