1. ホーム
  2. replace

[解決済み】Atomでタブをスペースに置き換えるには?

2022-02-20 09:02:53

質問

Atomテキストエディターで作業するようになり、タブインデントを使用していましたが、4スペースインデントに変更したいのです。

それに応じて更新する必要があるファイルがいくつかあります。

一番簡単な方法は何でしょうか?

どのように解決するのですか?

Atomには、このためのツールが組み込まれています

コマンドパレットを起動する ( シフト Cmd P Macの場合 Ctrl シフト P Windows/Linuxの場合)、「"convert space"」または「"convert tab"」を検索してください。これら3つのコマンドが利用可能であることがわかるはずです。

  • ホワイトスペース 空白をタブに変換する
  • ホワイトスペース タブをスペースに変換する
  • ホワイトスペース すべてのタブを空白に変換する

タブを変換する vs. すべてのタブを変換する

コメントで、"Convert Tabs to Spaces" を使用すると Python のインデントが壊れるという指摘がありましたが、"Convert Tabs to Spaces" ではインデントが壊れません。 すべて Tabs to Spaces"は正しく動作しました。この2つの違いは何かというご質問ですね。

答えがわからなかったので、探してみました。これは "whitespace" パッケージで定義されており、そのソースはGithubの以下のサイトにあります。 atom/whitespace .

で見る lib/whitespace.js は、こんなのを見つけました。

'whitespace:convert-tabs-to-spaces': () => {
  let editor = atom.workspace.getActiveTextEditor()

  if (editor) {
    this.convertTabsToSpaces(editor)
  }
},

'whitespace:convert-spaces-to-tabs': () => {
  let editor = atom.workspace.getActiveTextEditor()

  if (editor) {
    return this.convertSpacesToTabs(editor)
  }
},

'whitespace:convert-all-tabs-to-spaces': () => {
  let editor = atom.workspace.getActiveTextEditor()

  if (editor) {
    return this.convertTabsToSpaces(editor, true)
  }
}

見ての通り、ここで関連する関数は convertTabsToSpaces . convert all" バリアントでは、唯一の違いは、第2引数 (オプション) が渡され、その引数に true .

return this.convertTabsToSpaces(editor, true)

の定義を見てみると convertTabsToSpaces この違いは、正規表現がこのブーリアン引数の状態に応じて変更されることです。

convertTabsToSpaces (editor, convertAllTabs) {
  let buffer = editor.getBuffer()
  let spacesText = new Array(editor.getTabLength() + 1).join(' ')
  let regex = (convertAllTabs ? /\t/g : /^\t+/g)

  buffer.transact(function () {
    return buffer.scan(regex, function ({replace}) {
      return replace(spacesText)
    })
  })

  return editor.setSoftTabs(true)
}

ここで該当する行は

let regex = (convertAllTabs ? /\t/g : /^\t+/g)

つまり、quot;convert all"バリアントでは、正規表現は行頭へのアンカーを気にしません ( ^ は使用せず)、各タブは独自の置換となります(タブ文字のグループが1つの置換として扱われるのではなく、--)。 \t vs. \t+ ).

Pythonのインデントを壊した理由

どのようなファイルを使用したのかわかりませんが、私はこのような非常にシンプルなテストファイルを使用し、タブ文字で完全にインデントしています。

import foo

class Foo():
    def __init__(self):
        self.foo = True

    def bar(self, a, b):
        return a + b

"タブをスペースに変換"を使用すると、次のようになります。

import foo

class Foo():
    def __init__(self):
    self.foo = True

    def bar(self, a, b):
    return a + b

うおぉぉぉぉぉぉぉぉぉぉぉぉぉぉぉぉぉぉぉぉぉぉぉぉぉ これはもう SyntaxError . もう一度、"Convert で試してみてください。 すべて タブをスペースに変更する"。

import foo

class Foo():
    def __init__(self):
        self.foo = True

    def bar(self, a, b):
        return a + b

これは、最初のケースで、左マージンのタブのグループが コレクションとして のように、スペースベースのインデントに縮小されます。正規表現が ^\t+ 行が1、2、8、24のタブでインデントされていても関係なく、すべて1つのインデントレベルに置き換えられますが、スペースで構成されています。

正直、何が言いたいのかわからない...バグのような気がします。

2つ目のケースでは、すべてのタブがスペースに相当する幅に変換されます(つまり、各タブは、他のタブ文字に隣接していても、4つのスペースに変換されます)。

ということは、おそらくそっちがいいんでしょうね。

一つ注意点としては、左マージンに限定されなくなったことです。 ^ アンカー)なので、他の場所にタブ文字が埋め込まれている場合、それらも変換されます。私の経験では、これはコードでは普通のことではありませんが、一応ご参考までに。