diff --git a/common/content/buffer.js b/common/content/buffer.js index 6837abbd..b4927118 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -174,7 +174,8 @@ function Buffer() //{{{ } catch (e) { liberator.reportError(e) } }, - completer: function (context) completion.charset(context) + completer: function (context) completion.charset(context), + validator: Option.validateCompleter }); // FIXME: Most certainly belongs elsewhere. diff --git a/common/content/editor.js b/common/content/editor.js index a9e7789a..f2952281 100644 --- a/common/content/editor.js +++ b/common/content/editor.js @@ -894,12 +894,10 @@ function Editor() //{{{ else return false; - let oldbg, tmpBg; + let oldBg, tmpBg; try { let res = io.withTempFiles(function (tmpfile) { - io.writeFile(tmpfile, text); - if (textBox) { textBox.setAttribute("readonly", "true"); @@ -908,6 +906,10 @@ function Editor() //{{{ textBox.style.backgroundColor = "#bbbbbb"; } + if (!io.writeFile(tmpfile, text)) + throw "Input contains characters not valid in the current " + + "file encoding"; + this.editFileExternally(tmpfile.path); if (textBox) diff --git a/common/content/io.js b/common/content/io.js index 27c860a3..a3f3a248 100644 --- a/common/content/io.js +++ b/common/content/io.js @@ -169,6 +169,13 @@ function IO() //{{{ ////////////////////// OPTIONS //////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////{{{ + options.add(["fileencoding", "fenc"], + "Sets the character encoding of read and written files", + "string", "UTF-8", + { + completer: function (context) completion.charset(context), + validator: Option.validateCompleter + }); options.add(["cdpath", "cd"], "List of directories searched when executing :cd", "stringlist", cdpath, @@ -685,19 +692,21 @@ function IO() //{{{ * pathname or an instance of nsIFile. * @returns {string} */ - readFile: function (file) + readFile: function (file, encoding) { let ifstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); let icstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream); - let toCharset = "UTF-8"; + if (!encoding) + encoding = options["fileencoding"]; if (typeof file == "string") file = self.getFile(file); else if (!(file instanceof Ci.nsILocalFile)) throw Cr.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined + // How would you expect it to work? It's an integer. --Kris ifstream.init(file, -1, 0, 0); - icstream.init(ifstream, toCharset, 4096, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); // 4096 bytes buffering + icstream.init(ifstream, encoding, 4096, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); // 4096 bytes buffering let buffer = ""; let str = {}; @@ -734,12 +743,17 @@ function IO() //{{{ * permissions if the file exists. * @default 0644 */ - writeFile: function (file, buf, mode, perms) + writeFile: function (file, buf, mode, perms, encoding) { let ofstream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); - let ocstream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream); + function getStream(defaultChar) { + let stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream); + stream.init(ofstream, encoding, 0, defaultChar); + return stream; + } - let charset = "UTF-8"; // Can be any character encoding name that Mozilla supports + if (!encoding) + encoding = options["fileencoding"]; if (typeof file == "string") file = self.getFile(file); else if (!(file instanceof Ci.nsILocalFile)) @@ -754,11 +768,33 @@ function IO() //{{{ perms = 0644; ofstream.init(file, mode, perms, 0); - ocstream.init(ofstream, charset, 0, 0x0000); - ocstream.writeString(buf); - - ocstream.close(); - ofstream.close(); + let ocstream = getStream(0); + try + { + ocstream.writeString(buf); + } + catch (e) + { + liberator.dump(e); + if (e.result == Cr.NS_ERROR_LOSS_OF_SIGNIFICANT_DATA) + { + ocstream = getStream("?".charCodeAt(0)); + ocstream.writeString(buf); + return false; + } + else + throw e; + } + finally + { + try + { + ocstream.close(); + } + catch (e) {} + ofstream.close(); + } + return true; }, /** diff --git a/vimperator/locale/en-US/index.txt b/vimperator/locale/en-US/index.txt index 7209a436..565892ba 100644 --- a/vimperator/locale/en-US/index.txt +++ b/vimperator/locale/en-US/index.txt @@ -274,6 +274,7 @@ section:Options[option-index] ||'eventignore'|| List of autocommand event names which should be ignored + ||'exrc'|| Allow reading of an RC file in the current directory + ||'extendedhinttags'|| XPath string of hintable elements activated by [m];[m] + +||'fileencoding'|| Changes the character encoding that Vimperator uses to read and write files. ||'focuscontent'|| Try to stay in Normal mode after loading a web page + ||'followhints'|| Change the behaviour of [m][m] in Hints mode + ||'fullscreen'|| Show the current window fullscreen + diff --git a/vimperator/locale/en-US/options.txt b/vimperator/locale/en-US/options.txt index c81b2ec5..07578854 100644 --- a/vimperator/locale/en-US/options.txt +++ b/vimperator/locale/en-US/options.txt @@ -315,6 +315,13 @@ current page. ____ +|\'fenc'| |\'fileencoding'| +||'fileencoding'|| string (default: "UTF-8") +____ +Changes the character encoding that Vimperator uses to read and write files. +____ + + |\'nofc'| |\'nofocuscontent'| |\'fc'| |\'focuscontent'| ||'focuscontent' 'fc'|| boolean (default: off) ____