結論
ファイルの読み書きをする際にFileクラスを使いsetEncoding
で適切な文字コードを指定しましょう、以上。
蛇足
TextEditorであればCore Packagesのencoding-selectorでよしなに設定できるので問題ないが、例えばTablrのように独自の編集画面を作りファイルの読み書きをする場合は自身で文字コードを適切に処理する必要がある。
(なお、例に挙げたTablrは文字コードの処理を行っていないためUTF-8なCSVしか扱えない)
2016/01/18 Update
Tablr 0.10.0より文字コードの処理が入り、UTF-8以外の文字コードであっても扱えるようになった。
node-pathwatcher/file.coffee at master · atom/node-pathwatcherのreadSync
とwriteFileSync
の実装を見ると以下のようになっている。
readSync: (flushCache) ->
if not @existsSync()
@cachedContents = null
else if not @cachedContents? or flushCache
encoding = @getEncoding()
if encoding is 'utf8'
@cachedContents = fs.readFileSync(@getPath(), encoding)
else
iconv ?= require 'iconv-lite'
@cachedContents = iconv.decode(fs.readFileSync(@getPath()), encoding)
@setDigest(@cachedContents)
@cachedContents
writeFileSync: (filePath, contents) ->
encoding = @getEncoding()
if encoding is 'utf8'
fs.writeFileSync(filePath, contents, {encoding})
else
iconv ?= require 'iconv-lite'
fs.writeFileSync(filePath, iconv.encode(contents, encoding))
ここのgetEncoding
で取得している文字コードはsetEncoding
でセットした文字コードであるため、実際にファイルを読み書きする前に文字コードのセットが必要となる。
文字コードの変換にはiconv-liteを使っていることから、iconv-liteで対応できる文字コードであればFileクラスを使い適切な値をsetEncoding
で指定してやれば読み書きの際に変換のことを考える必要はなくなる。
文字コードの自動判定をしたい場合
残念ながらFileクラスには文字コードの自動判別処理が入っていない。
encoding-selectorには文字コードの自動判別処理が実装されているが、外部からこれを利用する方法はないため自前で実装しなければならないようだ。
detectEncoding: ->
filePath = @editor.getPath()
return unless fs.existsSync(filePath)
jschardet = require 'jschardet'
iconv = require 'iconv-lite'
fs.readFile filePath, (error, buffer) =>
return if error?
{encoding} = jschardet.detect(buffer) ? {}
encoding = 'utf8' if encoding is 'ascii'
return unless iconv.encodingExists(encoding)
encoding = encoding.toLowerCase().replace(/[^0-9a-z]|:\d{4}$/g, '')
@editor.setEncoding(encoding)